Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Attribute routing with Url.Action not resolving route

I cannot get @Url.Action to resolve to the url I am expecting based on the attribute route I have applied:

My action (SearchController but with [RoutePrefix("add")])

     [Route("{searchTerm}/page/{page?}", Name = "NamedSearch")]
     [Route("~/add")]
     public ActionResult Index(string searchTerm = "", int page = 1)
     {
       ...
     }

Call to Url.Action

@Url.Action("Index", new { controller = "Search", searchTerm = "replaceMe", page = 1 })

This results in a url of

/add?searchTerm=replaceMe&page=1

I would expect

/add/replaceMe/page/1

If I type the url manually then it resolves to the correct action with the correct parameters. Why doesn't @Url.Action resolve the correct url?

like image 381
Simon Avatar asked Mar 28 '16 20:03

Simon


People also ask

Can you enable attribute routing in MVC?

To enable Attribute Routing, we need to call the MapMvcAttributeRoutes method of the route collection class during configuration. We can also add a customized route within the same method. In this way we can combine Attribute Routing and convention-based routing. A route attribute is defined on top of an action method.

What is the purpose of URL routing in MVC?

The ASP.NET MVC framework includes a flexible URL routing system that enables you to define URL mapping rules within your applications. The routing system has two main purposes: Map incoming URLs to the application and route them so that the right Controller and Action method executes to process them.

How does attribute based routing work?

MVC 5 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web application. The earlier style of routing, called convention-based routing, is still fully supported.

What are the three main elements of routing in MVC 3?

The three segments of a default route contain the Controller, Action and Id.


2 Answers

Since you have a name for your pretty route definition, you may use the RouteUrl method.

@Url.RouteUrl("NamedSearch", new {  searchTerm = "replaceMe", page = 1})

And since you need add in the url, you should update your route definition to include that in the url pattern.

[Route("~/add")]
[Route("~/add/{searchTerm?}/page/{page?}", Name = "NamedSearch")]
public ActionResult Index(string searchTerm = "", int page = 1)
{
 // to do : return something
}
like image 104
Shyju Avatar answered Oct 17 '22 22:10

Shyju


Routes are order sensitive. However, attributes are not. In fact, when using 2 Route attributes on a single action like this you may find that it works on some compiles and not on others because Reflection does not guarantee an order when analyzing custom attributes.

To ensure your routes are entered into the route table in the correct order, you need to add the Order property to each attribute.

[Route("{searchTerm}/page/{page?}", Name = "NamedSearch", Order = 1)]
[Route("~/add", Order = 2)]
public ActionResult Index(string searchTerm = "", int page = 1)
{
    return View();
}

After you fix the ordering problem, the URL resolves the way you expect.

@Url.Action("Index", new { controller = "Search", searchTerm = "replaceMe", page = 1 })

// Returns "/add/replaceMe/page/1"
like image 25
NightOwl888 Avatar answered Oct 17 '22 21:10

NightOwl888