Routes in ASP.NET MVC 5 - asp.net-mvc

My requirement is I need to set multiple routes to same controller/action method.
If user enters url http://localhost:xxxx/home/index , it will target "index" action method of "home" controller.
I also want "http://localhost:xxxx/products" and "http://localhost:xxxx/categories" to point to "index" action method of "home" controller.
I was able to achive this by adding two routes "categories" and "products" as mentioned below , and it is working fine.
routes.MapRoute(
name: "categories",
url: "categories",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "products",
url: "products",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
My question is , is there any way I combine those two routes "categories" and "products" in to one ?

You can achieve this by adding a constraint to your route.
Make the entire path a parameter, and then assign a regular expression rule to match this parameter.
routes.MapRoute(
name: "IndexMapper",
url: "{alternateIndexName}",
defaults: new { controller="Home", action="Index" },
constraints: new { alternateIndexName="(categories)|(products)"}
);
https://msdn.microsoft.com/en-us/library/cc668201.aspx#Anchor_6

Related

How to set multiple routes to same action method in MVC 5?

I am working on single page application using MVC 5 and Angular 2.
My requirment is I need do set multiple routes to same controller/action method.
If user enters url http://localhost:xxxx/home/index , it will target "index" action method of "home" controller.
I also
want "http://localhost:xxxx/products" and "http://localhost:xxxx/categories" to point to "index" action method of "home" controller.
Note : Both "products" and "categories" are netiher controller or action methods.
Adding below 2 routes did the job.
routes.MapRoute(
name: "categories",
url: "categories",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "products",
url: "products",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

MVC Routing Issue when trying www.example.com/id

Let say I have a website www.example.com
the default routing looks like
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
Ok that works fine but let's say I want my site when I go to www.example.com/id to go to www.example.com/login/index/id
How would I configure/add routing for this, without breaking my other pages where I am actually trying to go to www.example.com/controller?
EDIT: Unfortunately id is a string so I do not have any concrete constraints that I can think of that would work. Think of maybe instead of the id I should have said companyname or sitename so the URL would look like www.example.com/companyname .
The only solution that I have come up with so far is adding a maproute for each one of my controllers like this
routes.MapRoute(
name: "Home",
url: "Home/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Settings",
url: "Settings/{action}/{id}",
defaults: new { controller = "Settings", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "companyname",
url: "{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
This will work but I have many controllers and if I add one in the future and forget to adjust the routes it will fail. Also, this is unlikely but if a companyname happens to the be same as one of my controller names it would also fail.
In controller you may redirect to another Controller/action:
public ActionResult yourAction()
{
return RedirectToAction("nameAction","nameController");
}
Did you tried adding this mapping first:
routes.MapRoute( name: "Custom", url: "{id}", defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional } );
That should work but keep in mind that routes are evaluated secuentially, so you will have to organize mappings in order to reach out all pages in your site.
For example, routes like www.example.com/Product could be redirected to /Login by mistake.
EDIT: You can add constraints, so if id is an int value, you can try with the following:
routes.MapRoute("Custom", "{id}",
new { controller = "Login", action = "Index" },
new { id = #"\d+" }
EDIT 2: Having ids as string values, the only solution I see is to manually add each controller as you said, or to add something like this:
routes.MapRoute(
name: "Default",
url: "app/{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
This way you don't need to update each route in the future.
Please try below routing
routes.MapRoute(name: "companylogin", url: "companylogin/{id}", defaults: new
{
controller = "Login",
action = "Index",
id = UrlParameter.Optional
});
routes.MapRoute(name: "default", url: "{controller}/{action}/{id}", defaults: new
{
controller = "Login",
action = "Index",
id = UrlParameter.Optional
});
Remove other controller specific routing. Now you can navigate to login using
url : - www.example.com/companylogin/{id} and all other url redirect default route.

Asp.net mvc routing without a controller or action name

I am trying to redirect all urls that don't match an existing controller to a certain controller.
For example, the url mywebsite.com/newyork should be processed as mywebsite.com/Cities/Info/newyork
I am using the following code in my RegisterRoutes but it doesn't seem to work as I get a 404 reponse:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Cities",
url: "{cityname}",
defaults: new { controller = "Cities", action = "Info", cityname= "" }
);
You should put your cities route first and drop the empty default parameter:
routes.MapRoute(
name: "Cities",
url: "{cityname}",
defaults: new { controller = "Cities", action = "Info" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The routes are processed in order so you should have most specific first to least specific ( your default route).
As your website.com/newyork matched the default route, it wasn't continuing to your city route.

Does MVC routes look for pattern or names

I am trying to understand routes, but am very confused.
The question is simply, does the default values have any impact on which router is chosen, or is it simply the pattern.
For example, consider the following
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{startIndex}",
defaults: new { controller = "Home", action = "Index", startIndex = UrlParameter.Optional }
);
routes.MapRoute(
name: "About",
url: "{controller}/{action}/{startIndex}",
defaults: new { controller = "About", action = "Index", startIndex = UrlParameter.Optional }
);
Regardless of whether the end result is the same, would MVC simply choose the first every time since the URL: pattern matches the request, and therefore ignore that they have different controllers?
Route selection uses pattern matching and will select the first matching pattern. In your example, there's no reason for your second route as the first will match /about/... as well as the second and result in the same action being invoked. If you need to have routes which have the same basic pattern, perhaps the values in the pattern affect the controller you use, you can use routing constraints to aid in choosing the correct route or use fixed values and place the route before the default route.
routes.MapRoute(
name: "Contact",
url: "/contact",
defaults: new { controller = "about", action = "contactus", id = "" }
);
routes.MapRoute(
name: "Help",
url: "/help",
defaults: new { controller = "about", action = "help", id = "" }
);
routes.MapRoute(
name: "Admin",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Admin", action = "Index", id= UrlParameter.Optional },
constraints: new { controller = "(admin)|(orgadmin)" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{startIndex}",
defaults: new { controller = "Home", action = "Index", startIndex = UrlParameter.Optional }
);

ASP.NET MVC 4 Routes - controller/id vs controller/action/id

I'm trying to add a route to the default one, so that I have both urls working:
http://www.mywebsite.com/users/create
http://www.mywebsite.com/users/1
This will make the first route work:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "users", action = "Index", id = UrlParameter.Optional }
);
However, the second route won't work obviously.
This will make the second route work, but will break the first one:
routes.MapRoute(
name: "Book",
url: "books/{id}",
defaults: new { controller = "users", action = "Details" }
);
How to combine the two route configurations so that both URLs work?
I apologize if there is already a question like this on SO, I wasn't able to find anything.
The key is to put more specific routes first. So put the "Book" route first. Edit I guess you also need a constraint to only allow numbers to match the "id" part of this route. End edit
routes.MapRoute(
name: "Book",
url: "books/{id}",
defaults: new { controller = "users", action = "Details" },
constraints: new { id = #"\d+" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "users", action = "Index", id = UrlParameter.Optional }
);
And ensure that the "id" parameter in your "Details" action is an int:
// "users" controller
public ActionResult books(int id)
{
// ...
}
This way, the "Books" route will not catch a URL like /users/create (since the second parameter is reqiured to be a number), and so will fall through to the next ("Default") route.

Resources