Search code examples
asp.net-coreasp.net-core-mvcasp.net-mvc-routing

Why is mandatory the "Route" attribute on methods of a custom-routed controller?


Consider a fresh Asp.Net Core 2.1 MVC Web app created via the Visual Studio 2017 template. Now, consider a custom view (MyView) and also a controller (ActualController) so that the project structure looks similar to this picture:

enter image description here

The MyView shows nothing special, and it's off the point. However, the page should appear when the user enters an URL like http://(domain)/desired/myview or also via a hyperlink in the home page:

<a asp-area="" asp-controller="Desired" asp-action="MyView">MyView</a>

Now let's focus on the controller, which is a class named differently from what the routing expects:

[Route("desired")]
public class ActualController : Controller
{
    [Route("MyView")]  //without this the method won't be called
    public IActionResult MyView()
    {
        return this.View();
    }
}

From what I know, by decorating the controller with a Route attribute tells the URL resolver to match this class. However, the mapping works only if I explicitly add a (redundant) Route attribute on the target method/action. If I remove it, the path won't be found, and the server returns a 404-error.

The question is: why should be mandatory to decorate with Route the method, even the action is implicitly defined by the method name (as usual)?

NOTE: is rather simple for me to rename the controller class, but I'd like to know what are the reasons behind this behavior.


Solution

  • You are overriding the default route of [controller]/[action] with [Route("desired")]. Since you don't define an action parameter on controller level, all other routes have to be done explicitly.

    Changing the top route parameter to [Route("desired/[action]")] should solve it and the method name will be used as parameter. You can still override single actions if you want to name them differently by adding the [Route("")] attribute to them.

    Also see the docs (Token replacement in route templates) for further description on the route parameters