为什么必须在自定义路由控制器的方法上强制使用“ Route”属性?

时间:2018-10-23 08:49:41

标签: asp.net-core asp.net-core-mvc asp.net-mvc-routing

请考虑通过Visual Studio 2017模板创建的新的Asp.Net Core 2.1 MVC Web应用程序。现在,考虑一个自定义视图(MyView)和一个控制器(ActualController),以便项目结构看起来类似于此图片:

enter image description here

MyView没什么特别之处,这是没有道理的。但是,当用户输入http://(domain)/desired/myview之类的URL或通过主页中的超链接输入时,该页面也会出现:

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

现在,让我们集中讨论控制器,这是与路由期望的名称不同的类

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

据我所知,通过使用Route属性修饰控制器,可以告诉URL解析器匹配该类。但是,仅当我在目标方法/操作上明确添加(冗余)Route属性时,映射才起作用。如果删除它,将找不到该路径,并且服务器返回404错误。

问题是:为什么要强制使用Route装饰方法,即使动作是由方法名称隐式定义的(通常)?

注意:重命名控制器类对我来说很简单,但是我想知道此行为背后的原因是什么。

1 个答案:

答案 0 :(得分:1)

您正在用[controller]/[action]覆盖[Route("desired")]的默认路由。由于您没有在控制器级别定义动作参数,因此必须明确完成所有其他路由。

将顶级路由参数更改为[Route("desired/[action]")]应该可以解决该问题,方法名称将用作参数。如果您想通过将[Route("")]属性添加到单个动作来命名其他动作,则仍然可以覆盖它们。

有关路线参数的进一步说明,请参见docs (Token replacement in route templates)