views:

722

answers:

3

On an ASP.NET MVC (Beta) site that I am developing sometimes calls to ActionLink will return to me URLs containing querying strings. I have isolated the circumstances that produce this behavior, but I still do not understand why, instead of producing a clean URL, it decides to using a query string parameter. I know that functionally they are the same, but for consistency (and appearance) of the URLs this is not what I want.

Here are my routes:

        routes.MapRoute(
                        "Photo Gallery Shortcut",
                        "group/{groupname}",
                        new { controller = "Photos", action = "All", Id = "" });

        routes.MapRoute(
                        "Tagged Photos", //since the Tagged action takes an extra parameter, put it first
                        "group/{groupname}/Photos/Tagged/{tagname}/{sortby}",
                        new { controller = "Photos", action = "Tagged", Id = "", SortBy = "" });

        routes.MapRoute(
                        "Photo Gallery", //since the Gallery's defualt action is "All" not "Index" its listed seperatly
                        "group/{groupname}/Photos/{action}/{sortby}",
                        new { controller = "Photos", action = "All", Id = "", SortBy = "" });

        routes.MapRoute(
                        "Group",  //<-- "Group" Category defined above
                        "group/{groupname}/{controller}/{action}/{id}",
                        new {controller = "Photos", action = "Index", Id = ""});

Now the problem only occurs when I am looking at the view described by the route named "Tagged Photos" and execute ActionLink via:

Html.ActionLink<PhotosController>(p => p.All((string)ViewData["group"], ""), "Home")

Which produces the URL:

http://domain/group/GROUPNAME?sortBy=

From any other view the URL produced is:

http://domain/group/GROUPNAME

I have pulled down Phil's ASP.NET Routing Debugger, and everything appears in order. This one has me stumped. Any ideas?

A: 

I think it is picking up your first Route. It too has the action All. And because the sortby is not specified it is exposing it as a querystring parameter

This will still work with the action method 'All' on the PhotosController, because it just fills the sortby parameter with the query string value.

In the Route Debugger is it executing the 3rd route or the 1st?

Schotime
+3  A: 

Not sure why different views are producing different URLs.

But you can get rid of that sortBy param by assigning a default value to the first route.

new { sortBy = "" }

During generation, if sortBy matches the default, the route engine will skip that parameter (if it's in the query string).

CVertex
Ah, I overlooked that in the Route Debugger the query string URL was executing that first route. Adding the SortBy = "" to that first route's defaults resolves it in this case, but won't I have the same problem If I later try to sort by something specific? Do I just remove that first route?
Jason Whitehorn
When you specify another sortBy value, the sortBy=blah querystring param will be added.
CVertex
+1  A: 

You're going to have to use named routes here, not action routes, because of the way routing works in ASP.NET, because it does "first match", not "best match".

Brad Wilson