If the list of your actions (for example, Submit) is well known, and their names (actions) cannot coincide with some identifier value, we can use our custom ConstraintImplementation:
public class MyRouteConstraint : IRouteConstraint { public readonly IList<string> KnownActions = new List<string> { "Send", "Find", ... }; // explicit action names public bool Match(System.Web.HttpContextBase httpContext, Route route , string parameterName, RouteValueDictionary values , RouteDirection routeDirection) { // for now skip the Url generation if (routeDirection.Equals(RouteDirection.UrlGeneration)) { return false; // leave it on default } // try to find out our parameters string action = values["action"].ToString(); string id = values["id"].ToString(); // id and action were provided? var bothProvided = !(string.IsNullOrEmpty(action) || string.IsNullOrEmpty(id)); if (bothProvided) { return false; // leave it on default } var isKnownAction = KnownActions.Contains(action , StringComparer.InvariantCultureIgnoreCase); // action is known if (isKnownAction) { return false; // leave it on default } // action is not known, id was found values["action"] = "Index"; // change action values["id"] = action; // use the id return true; }
And the route map (before by default - both should be provided) should look like this:
routes.MapRoute( name: "DefaultMap", url: "{controller}/{action}/{id}", defaults: new { controller = string.Empty, action = "Index", id = string.Empty }, constraints: new { lang = new MyRouteConstraint() } );
Summary In this case, we evaluate the value of the action parameter.
- if both 1) action and 2) id are provided, we will not process it here.
- and if it is a known action (listed or reflected ...).
- only if the action name is unknown, change the route values: set the "Index" action and the action value for the ID.
NOTE: action names and id values โโmust be unique ... then this will work
Radim Kรถhler
source share