TPR
TPR

Reputation: 2577

asp.net mvc routing - is this possible?

can I have domain.com/action/id as well as domain.com/controller/action?

how would I register these in the route-table?

Upvotes: 1

Views: 105

Answers (2)

Michael Stum
Michael Stum

Reputation: 181004

Is ID always guaranteed to be a number? If yes, then you could use RouteConstraints:

routes.MapRoute("ActionIDRoute",
               "{action}/{id}",
               new { controller = "SomeController" },
               new {id= new IDConstraint()});
routes.MapRoute("ControllerActionRoute",
                "{controller}/{action}",
                new {}); // not sure about this last line

The IDConstraint class looks like this:

public class IDConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route,
                      string parameterName, RouteValueDictionary values,
                      RouteDirection routeDirection)
    {
        var value = values[parameterName] as string;
        int ID;
        return int.TryParse(value,out ID);
    }
}

Basically what is happening is that you have two identical routes here - two parameters, so it's ambigous. Route Constraints are applied to parameters to see if they match.

So:

  1. You call http://localhost/SomeController/SomeAction
  2. It will hit the ActionIDRoute, as this has two placeholders
  3. As there is a constraint on the id parameter (SomeAction), ASP.net MVC will call the Match() function
  4. As int.TryParse fails on SomeAction, the route is discarded
  5. The next route that matches is the ControllerActionRoute
  6. As this matches and there are no constraints on it, this will be taken

If ID is not guaranteed to be a number, then you have the problem to resolve the ambiguity. The only solution I am aware of is hardcoding the routes where {action}/{id} applies, which may not be possible always.

Upvotes: 2

AxelEckenberger
AxelEckenberger

Reputation: 16926

Yes, you can add a new rule above the default rule and provide a default value for the controller.

routes.MapRoute(
  "MyRole",  // Route name
  "{action}/{id}",  // URL with parameters
  new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

The sample routs all actions to the "Home" controller.

Upvotes: 1

Related Questions