Multiple routes assigned to one method, how to determine which route was called?
Asked Answered
R

3

18

I am working on a small ASP.NET MVC project at the moment. The project was released a few month ago. But changes should be implemented for usability and SEO reasons now. I decided to use attribute routing to create clean URLs.

At the moment a product page is called by:

hostname.tld/Controller/GetArticle/1234

I defined a new Route like this:

[Route("Shop/Article/{id:int}/{title?}", Name = "GetArticle", Order = 0)]
public ActionResult GetArticle(int id, string title = null) {
    // Logic
}

Everything works fine, but because of backwards compatibility and SEO reasons, the old route should be still available. And redirected with HTTP status code 301 to the new URL.

I've heard that it is possible to assign multiple routes to one action, like this:

[Route("Shop/Article/{id:int}/{title?}", Name = "GetArticle", Order = 0)]
[Route("Controller/GetArticle/{id:int}", Name = "GetArticle_Old", Order = 1)]
public ActionResult GetArticle(int id, string title = null) {
    // Logic
}

But I have no idea if this is a good solution or how to determine which route was called?

Rai answered 21/9, 2016 at 16:16 Comment(4)
Which version of MVC are you using? You can get the route info via this.ControllerContext.RouteData possibly.Hendrick
ASP.NET MVC 4.5.2 , so I think MVC 5 , multiple Route tags are not supported on earlier version as far as I know. And thank you I will check this out !Rai
I asked because if you were using Core MVC, you'd need to use dependency injection to get an equivalent to ControllerContext I believe.Hendrick
@stephen.vakil Thank you very much for pointing in the right direction ! I solved my question with your comment. If you want write it down as answer and I'll accept it ;) Have a nice day !Rai
H
14

You can look at ControllerContext.RouteData to figure out which route they used when using multiple routes for one action.

public const string MultiARoute = "multiA/{routesuffix}";
public const string MultiBRoute = "multiB/subB/{routesuffix}";

[Route(MultiARoute)]
[Route(MultiBRoute)]
public ActionResult MultiRoute(string routeSuffix)
{

   var route = this.ControllerContext.RouteData.Route as Route;
   string whatAmI = string.Empty;

   if (route.Url == MultiARoute)
   {
      whatAmI = "A";
   }
   else
   {
      whatAmI = "B";
   }
   return View();
}
Hendrick answered 21/9, 2016 at 20:32 Comment(0)
E
9

I wanted to be able to pass different views based on the request but they all basically used the same process and didn't want to make an action for each. The prior answer doesn't seem to work any more so here is what I came up with. This is .Net Core 2.2.

 [HttpGet]
[Route("[controller]/ManageAccessView/{name}/{id}",Name = "ManageAccessView")]
[Route("[controller]/ManageAccessUsers/{name}/{id}", Name = "ManageAccessUsers")]
[Route("[controller]/ManageAccessKeys/{name}/{id}", Name = "ManageAccessKeys")]
public async Task<IActionResult> ManageAccessView(int id, string name)
{

  var requestedView = this.ControllerContext.ActionDescriptor.AttributeRouteInfo.Name;

  return View(requestedView);


}

This will allow you to put your individual views as the name of the routes and use them to set the view.

Extensive answered 25/1, 2019 at 16:28 Comment(1)
Also, if we want a form to post to the the route used with the controller action, we can use this named route in the form tag like so: <form asp-route="@ViewContext.ActionDescriptor.AttributeRouteInfo.Name" ...>Zacharyzacherie
T
2
    [HttpGet("api/route1")]
    [HttpGet("api/route2")]
    [HttpGet("api/route3")]
    public void example ()
    {
        string requestedRoute = this.ControllerContext.HttpContext.Request.Path.ToString();
        if(requestedRoute == "/api/route1"){
            //do something
        }
    }

This works for me.

Transcendentalism answered 29/11, 2021 at 18:57 Comment(1)
small note: this.ControllerContext.HttpContext.Request.Path.Value is a string, watch out it might contains also the Route defined on controller level, like [Route("api/[controller]")]Phone

© 2022 - 2024 — McMap. All rights reserved.