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:
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.
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