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?
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.
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.
The default MVC mapping is /[Controller]/[ActionName]/[Parameters] . For this URL, the controller is HelloWorld and Welcome is the action method.
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.
Why does the first URL in the new list still have "Customer". I assume that's a typo and you meant:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With