Martin Hansen
Martin Hansen

Reputation: 5224

ASP.NET MVC Routing help

I am trying to create a route that can allow for different formats (html/json/xml etc)

This is what I am trying, but it doesn't work.

routes.MapRoute(
          "Default",
          "{controller}/{action}/{id}/{format}",
          new { controller = "Home", action = "Index", id = UrlParameter.Optional, format = "html" },
          new { format = @"html|json" , id=@"\d+"}
       );

The routes that do work are these: /Person/details/1 /Person/details/1/json

But this don't work: /Person which imo should default to /Person/Index/html /Person/json and imo should lead to /Person/Index/json

But it doesn't match.

For the second of the ones that don't work I assume it thinks json is an action and that's the problem there, but for the first one I don't fully get it as I have defaults for each part of the url, and id is optional and it can't think html/json is the id as I say id have to be a number anyway, so it should imo get that one.

So who aren't the first one working?

For the second one I have been meaning to write a regex like this (I know it's not a real regex btw, any help on that is also appreciated..): action = @"!(html|json|\d+)" so that it will see that I'm not trying to say that json/html is an action, but that it then should use the default action of index.

But since the first one isn't even working I think I have to resolve that one first.

Upvotes: 0

Views: 280

Answers (2)

Robert Koritnik
Robert Koritnik

Reputation: 105081

The problem

Routes can have multiple optional parameters (although I suggest you don't use this unless you know Asp.net MVC routing very well), but you can't have non-optional parameters after optional ones as you've done it...

Imagine what would happen if you set a non-default "json" value for your format but don't provide id? What would come in place of the id? You'd run against a very similar problem with multiple optionals, hence I advise you not to use them.

Two solutions

  1. Change parameter order:

    "{controller}/{action}/{format}/{id}"
    
  2. Use two routes

    routes.MapRoute(
        "Ordering",
        "{controller}/{action}/{format}",
        new { controller = "Home", action = "Index", format = "html" },
        new { format = @"html|json|xml"}
    );
    
    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}/{format}",
        new { controller = "Home", action = "Index", format = "html" },
        new { format = @"html|json|xml", id = @"\d+"}
    );
    

    The first one will cover requests where ID is optional and you do provide format, and the second one will cover situations when ID is present.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1039438

The id parameter cannot be optional. Only the last parameter of a route definition can be optional.

Upvotes: 0

Related Questions