tags:

views:

46

answers:

2

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

how would I register these in the route-table?

+1  A: 

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.

Obalix
and what rule would take care of the domain.com/controller/action route? I have AccountController that has LogOn actionresult defined. However, domain.com/account/logon is not being catched by the routetable.
progtick
The default rule does.
Obalix
+1  A: 

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.

Michael Stum
well, id is guaranteed to be a number for now, but who knows when the project expands, if you know what I mean.
progtick
Michael Stum
I agree. I will ponder over this. In the meanwhile, your solution of using constraint works for me.
progtick