Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning multiple routes to the same controller or action in ASP MVC 6

Question:

Is there any way to assign two different routes (with parameters) to the same controller in an ASP.NET MVC 6 application?

I Tried:

I tried using multiple route attributes to the controller class and also to the individual actions, did not work.

Notes:

  • I am using ASP.NET Core 1.0 RC1.

  • The reason I want to do this is, I want the api to be compatible with the older version of our mobile app which use the old URL.

Example:

[Produces("application/json")] [Route("api/v2/Log")] /// The old route is "api/LogFile" which I want to be still valid for this controller. public class LogController : Controller {     [HttpGet("{id}", Name = "download")]     public IActionResult GetFile([FromRoute] Guid id)      {         // ...     } } 

In the example above: api/LogFile/{some-guid} is the old route and api/v2/log/download/{some-guid} is the new route. I need both routes invoke the same action.

like image 589
A-Sharabiani Avatar asked Feb 09 '16 15:02

A-Sharabiani


People also ask

Can we have multiple routes in MVC?

Multiple Routes You need to provide at least two parameters in MapRoute, route name, and URL pattern. The Defaults parameter is optional. You can register multiple custom routes with different names.

Can we map multiple URLs to the same action?

Yes, We can use multiple URLs to the same action with the use of a routing table. foreach(string url in urls)routes. MapRoute("RouteName-" + url, url, new { controller = "Page", action = "Index" });

Can a controller have multiple get methods?

Usually a Web API controller has maximum of five actions - Get(), Get(id), Post(), Put(), and Delete(). However, if required you can have additional actions in the Web API controller.

How many routes can be defined in the MVC application?

there are no limits in creating routes. You can create as many route as you want in your RouteConfig.


1 Answers

Having 2 route attributes at the controller level works fine in a new RC1 application:

[Produces("application/json")] [Route("api/[controller]")] [Route("api/old-log")] public class LogController: Controller {     [HttpGet]     public IActionResult GetAll()     {         return Json(new { Foo = "bar" });     } } 

Both http://localhost:62058/api/log and http://localhost:62058/api/old-log return the expected json. The only caveat I have seen is that you might want to set the name/order properties of the attributes in case you need to generate the url to one of those actions.

Having 2 Attributes on the action also works:

[Produces("application/json")]         public class LogController : Controller {     [Route("api/old-log")]     [Route("api/[controller]")]     [HttpGet]     public IActionResult GetAll()     {         return Json(new { Foo = "bar" });     } } 

However you need to be careful when having a general route at the controller level and a specific action route. In these cases the route at the controller level is used as a prefix and prepended to the url (There is a nice article about this behavior here). This might get you a different set of urls than you were expecting, for example with:

[Produces("application/json")] [Route("api/[controller]")] public class LogController : Controller {     [Route("api/old-log")]     [Route("")]     [HttpGet]     public IActionResult GetAll()     {         return Json(new { Foo = "bar" });     } } 

The 2 routes that your application will listen in the last case will be http://localhost:62058/api/log and http://localhost:62058/api/log/api/old-log since api/log is added as prefix to all the routes defined at the action level.

Finally, another option would be to use attributes for your new routes and then use the route table in the startup class to provide specific routes that take care of the old api.

like image 67
Daniel J.G. Avatar answered Sep 23 '22 20:09

Daniel J.G.