-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: ignoreRouteParameters #404
Comments
To what end? Why are your routes including the ID if you don't want them generated there? You could make your routes URLs and they would ignore the ID when they are generated.
More to the point, why do you need |
Let me try a better example. We have routes to pages with optional parameters:
We use sitemap to navigate to the pages and we never want to see ID persisted in the sitemap.
We have a search UI that handles sending the user to the page with ID (nothing to do with sitemap)
This simple structure worked under 3.x. When we upgraded to 4.x we had to add We are trying to get back to the 3.x behavior without persisting values into the sitemap. Here is our work around to match without public class MvcSiteMapIgnoreParameters : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionDescriptor != null && filterContext.ActionDescriptor.ControllerDescriptor != null)
{
// look up node where key = "{controller}.{action}"
string action = filterContext.ActionDescriptor.ActionName;
string controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
var node = SiteMaps.Current.FindSiteMapNodeFromKey(string.Format("{0}.{1}", controller, action));
// if we find a node then add all paremeters into the RouteValues collection so they will match
if (node != null)
{
foreach (var item in filterContext.RouteData.Values)
{
if (item.Key != "controller" && item.Key != "action")
{
node.RouteValues[item.Key] = item.Value;
}
}
}
}
base.OnActionExecuting(filterContext);
}
} |
Ok, so you were relying on the broken "partial" matching behavior of 3.x. That has been fixed because there were several people who insisted that they needed to use the same controller and action for both the parent and child node, and the only way to get them both to work is to ensure the parent node doesn't match the request without the parameter (see this). So you want your incoming and outgoing URLs to be different. This is exactly the problem that .NET routing was created to fix. But that doesn't mean you can't still do it using routing. public class IgnoreParametersRoute : Route
{
private readonly string[] ignoredParameters;
public IgnoreParametersRoute(string url, object defaults, string[] ignoredParameters)
: base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
{
this.ignoredParameters = ignoredParameters == null ? new string[0] : ignoredParameters;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
var nonIgnoredRouteValues = new RouteValueDictionary(values.Where(param => !ignoredParameters.Contains(param.Key)).ToDictionary(t => t.Key, t => t.Value));
return base.GetVirtualPath(requestContext, nonIgnoredRouteValues);
}
} Which can be used like: routes.Add(
name: "Default",
item: new IgnoreParametersRoute(
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
ignoredParameters: new string[] { "id" }
)
); After all, why would you want MvcSiteMapProvider's behavior to differ from how an action link would normally be created (because MVC automatically copies values over from the request just like preservedRouteParameters does). If that doesn't suit your taste, there are several other ways to accomplish this:
As for a first class feature, most people do not expect their incoming and outgoing routes to be different so I doubt anyone else would find it useful. Eventually, I plan to make the matching behavior customizable, which will make things like this possible to do, but for now you can use one of these alternatives. |
Allowing the matching behavior to be customized (or simplified) would be great. It's the one issue I see come up again and again. Something like |
Would it be possible to add a node setting like ignoreRouteParameters (opposite of preserveRouteParametrs). To tell the matching code to ignore the listed parameters.
We want matching (but not preserving) for this scenario when ignoreRouteParameters="id"
We currently use preserveRouteParametrs="id" to get this to work for "/person/edit/{id}" and "/order/edit/{id}" routes but this has the side effect of adding "id" to the links in the sitemap for both order and person which we do not need or want.
/person/edit/123
/order/edit/123
The text was updated successfully, but these errors were encountered: