I am just getting started with ASP.NET MVC and it's great! However, I don't quite understand setting up routes.
How do I route ~/About to ~/Home/About?
/Views/Home/About.aspx
I would like to be able to access it with
/Home/About
or just
/About
If you want to explicity setup a route for it, you can do something like this:
routes.MapRoute(
"AboutRoute",
"About",
new { controller = "Home", action = "About" } // Parameter defaults
);
I think thats what you want to do? I.e. have /About handled by the home controller?
The default route (as below) handles /Home/About
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
In response to your comment on RM's answer - you don't actually need wildcards for that. Just do
routes.MapRoute(
"AllToHomeController",
"{action}/{id}",
new { controller = "Home", action = "Index", id = "" });
Note, however, that you need to place this route at the very end of your route table (and you'll have to delete the default route), as this will catch every url that comes in.
You can use Phil Haack's Route Debugger to verify that your routes pick up urls as you expect.
Related
I am new to ASP.NET MVC5, I found one default route in routeconfig.cs file.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
so, If I am trying to access localhost:44300, I am redirecting to Home/Index action method.
So I am added Login page in Home/Index view page. after user successful login I am redirecting the user to Home/Details Method then In browser I am getting url as https://localhost:44300/Home/Details.
Here my question Is there any possibility to hide Home/Details like Home/Index. I am tried with adding another default route but it is failed.
Try adding following route before your default route in RouteConfig.cs file -
routes.MapRoute(name: "Details",
url: "Home/Index/{id}",
defaults: new { controller = "Home", action = "Details", id = UrlParameter.Optional }
);
This will convert - Home/Details to Home/Index
It is impossible to have the same url (http://localhost:44300) be mapped to 2 different controller actions. There can only be one default route.
I'm trying to achieve this goal of changing my apps routes to look like this:
hxxp://host/MyController/Widgets/3/AddWhatsit
The view for this route would help a user add a Whatsit to Widget 3.
Similarly, I would expect the route to create a new Widget to be:
hxxp://host/MyController/Widgets/Create
I've created separate routes to try and facilitate this. They are:
routes.MapRoute("DefaultAction",
"{controller}/{action}",
new {controller = "Home", action = "Index"});
routes.MapRoute("Default",
"{controller}/{id}/{action}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional});
The problem I'm having is that when I browse to the Index page for Widgets (/MyController/Widgets, matching the "DefaultAction" route) Any ActionLinks that would introduce a new url parameter that's not part of that route gets turned into a querystring value. So, for example, the edit link for Widget 3 would render as:
Widget/Edit?id=3
instead of (what I would prefer):
Widget/3/Edit
I guess I understand that I'm messing things up by not putting my (optional) id param at the end of the route.
Should I suck it up and just leave id at the end of the route?
It is possible to achieve this. To get anchor link looking like /Home/1/Index, set routes like:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Custom",
url: "{controller}/{id}/{action}"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
And then, in the View:
#Html.ActionLink("Here", "Index", "Home", new { id = 5 }, null)
And you get link rendered like this:
Here
Quirk is to constrain custom route. I removed defaults in this case, they do not make sense. And order of routes, of course.
I believe you need to change the order of your routes. Remember, that MVC looks down the route list and picks the First matching route. Your second route with the ID parameter is more specific and as such, should come first in your routing table.
Even though you have specified an ID parameter in your ActionLink, you have also specified a controller and an action. Therefore, the first route is being chosen by the RoutingEngine.
Lastly, remove the optional parameter for the ID attribute. Since you want that route to be chosen when you have an Id, then you do not want that to be an optional parameter, you want it to be required to match that route.
routes.MapRoute("Default","{controller}/{id}/{action}",
new {controller = "Home", action = "Index"});
routes.MapRoute("DefaultAction", "{controller}/{action}",
new {controller = "Home", action = "Index"});
I have these two routes:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default2", // Route name
"{controller}/{action}/{OrderId}/{CustomerID}", // URL with parameters
new { controller = "NorthwindOrders", action = "Index", OrderId = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults
);
and want to create link that uses the second route.
How can I do this?
If you want to specifically use a route, you can use the Html helper Html.RouteLink :
<%= Html.RouteLink("my link", "Default2", new {OrderId=1, CustomerId=2}) %>
Also, you can put the second route first : the most generic route should be at the end, in order to be used only when no specific route was found.
Order is very important w/ MapRoutes. Try reversing the order of those two statements.
As well you should use definition of routes in different order.
the order should be more specific first to less
also in your action links i would add routing parameters
Actually not 100% what the OP asked for, but what I needed was an ActionResult that forcefully uses a specific route. RedirectToAction always used the wrong route. I found it in RedirectToRoute("RouteName", new { action="Index" }).
I define routes in my global.asax, like this:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
Given a url:
/somecontroller/someaction/3
is it possible to determine which route this will map to, and get the corresponding route object, with name, url template and defaults?
Thanks
Phil Haack has a blog post with an ASP.NET Routing Debugger that will let you debug any and all routes.
In my routing I would like to have something like not found route handler.
For example I have created one mapping like
routes.MapRoute(
"default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id="" }
);
routes.MapRoute(
"Catchall",
"{*catchall}",
new { controller = "Home", action = "Lost" }
);
but when user inserts address something like /one/two/three/four/bla/bla it will be cached with the Catchall mapping.
But when user inserts something that should match with default mapping,
(like /one/two/ ,but this controller or action is not implemented)
I would want that Catchall mapping would accept this request,
because all other mappings failed. But instead of this I get an error.
Should I override some mapping handlers to catch the exception if controller or action getting an exception?
The issue here is that it's not the Route's responsibility to make sure that "one/two" maps to a file. That responsibility falls to the ViewEngine. Since "one/two" is a valid route, it will be chosen.
If you want to handle the error of an invalid route, what I would recommend you do is simply use the built in ErrorHandling "page" to display whatever message you would have done in the Catchall.
I don't think this is the best solution, but you could always be more specific on your routes:
routes.MapRoute(
"home and action",
"home/index/{id}",
new { controller = "Home", action = "Index", id="" }
);
... repeat for the rest of your actions ...
routes.MapRoute(
"article catch all",
"home/{article}",
new { controller = "Home", action = "ArticleSearcher", article="" }
);
This would attempt to match a direct action, and if no action is found, pass what would normally be the {action} part of the default route to the 'ArticleSearcher' action as an article string parameter.
The downside is having to explicitly create each controller/action route.