Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Routing with Default Controller

For a scenario, I have a ASP.NET MVC application with URLs that look like the following:

http://example.com/Customer/List
http://example.com/Customer/List/Page/2
http://example.com/Customer/List
http://example.com/Customer/View/8372
http://example.com/Customer/Search/foo/Page/5

These URLs are achieved with following routes in Global.asax.cs

routes.MapRoute(
    "CustomerSearch"
    , "Customer/Search/{query}/Page/{page}"
    , new { controller = "Customer", action = "Search" }
);

routes.MapRoute(
    "CustomerGeneric"
    , "Customer/{action}/{id}/Page/{page}"
    , new { controller = "Customer" }
);

//-- Default Route
routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Customer", action = "Index", id = "" }
);

These all have gone well until a new requirement arrived and wants to drop keyword 'Customer' off the URL, to make the URLs look like:

http://example.com/List
http://example.com/List/Page/2
http://example.com/List
http://example.com/View/8372
http://example.com/Search/foo/Page/5

Edit: corrected example links, thanks to @haacked.

I tried to add new MapRoutes to take {action} only and have default controller set to Customer. eg/

routes.MapRoute(
    "CustomerFoo"
    , "{action}"
    , new { controller = "Customer", action = "Index" }
);

This seems to work, however now all links generated by Html.ActionLink() are weird and no longer URL friendly.

So, is this achievable? Am I approaching in the right direction?

like image 512
Trav L Avatar asked Nov 11 '09 06:11

Trav L


People also ask

What is default routing in MVC?

The Default route maps the first segment of a URL to a controller name, the second segment of a URL to a controller action, and the third segment to a parameter named id. The Default route maps this URL to the following parameters: controller = Home. action = Index.

How can add route in ASP.NET MVC?

In this tutorial, you learn how to add a custom route to an ASP.NET MVC application. You learn how to modify the default route table in the Global. asax file with a custom route. For many simple ASP.NET MVC applications, the default route table will work just fine.

What is default controller in MVC?

The default MVC mapping is /[Controller]/[ActionName]/[Parameters] . For this URL, the controller is HelloWorld and Welcome is the action method.


2 Answers

don't mix a rule like: "{action}/{id}" with one that's "{controller}/{action}/{id}" ... specially when id in the later has a default value i.e. is optional.

In that case you have nothing that allows routing to know which one is the right one to use.

A workaround, if that's what you need, would be to add a constrain (see this) to the action in the earlier to a set of values i.e. List, View. Of course that with these types of rules, you can't have a controller with the same name of an action.

Also remember that if you specify a default action & id in the "{action}/{id}" rule, that will be used when you hit the route of your site.

like image 197
eglasius Avatar answered Oct 07 '22 23:10

eglasius


Why does the first URL in the new list still have "Customer". I assume that's a typo and you meant:

  • http://example.com/List
  • http://example.com/List/Page/2
  • http://example.com/List
  • http://example.com/View/8372
  • http://example.com/Search/foo/Page/5

The following routes work for me:

routes.MapRoute(
    "CustomerSearch"
    , "Search/{query}/Page/{page}"
    , new { controller = "Customer", action = "Search" }
);

routes.MapRoute(
    "CustomerGeneric"
    , "{action}/{id}/Page/{page}"
    , new { controller = "Customer" }
);

//-- Default Route
routes.MapRoute(
    "Default",
    "{action}/{id}",
    new { controller = "Customer", action = "Index", id = "" }
);

How are you generating your links. Since the Controller is no longer in the URL of your route (aka, you don't have "{controller}" in the route URL), but it's a default value, you need to make sure to specify the controller when generating routes.

Thus instead of

Html.ActionLink("LinkText", "ActionName")

do

Html.ActionLink("LinkText", "ActionName", "Customer")

Why? Suppose you had the following routes.

routes.MapRoute(
    "Default",
    "foo/{action}",
    new { controller = "Cool" }
);

routes.MapRoute(
    "Default",
    "bar/{action}",
    new { controller = "Neat" }
);

Which route did you mean when you call this?

<%= Html.ActionLink("LinkText", "ActionName") %>

You can differentiate by specifying the controller and we'll pick the one that has a default value that matches the specified one.

like image 23
Haacked Avatar answered Oct 07 '22 23:10

Haacked