[英]MVC Attribute Routing RoutePrefix does not work with default routing
我有一个变通方法,但我真的很想知道为什么这在 MVC 中似乎不起作用。 (.Net 4.6.1)
我有一个我想使用 RoutePrefix 的控制器:
[RoutePrefix("entry")]
public class DefaultController : Controller
{
[HttpGet]
[Route(), Route("Index")]
public ActionResult Index()
{
// ...
}
}
在路由配置中:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "entry", action = "index", id = UrlParameter.Optional }
问题是使用此配置,在本地 IIS 下运行进行测试,导航到“localhost/testApp/entry”有效,“localhost/testApp/entry/index”有效,但是默认的“localhost/testApp/”导致 404 .
这一直是我的头脑,因为在一个带有默认控制器和默认设置为“home”和“index”的新项目中,“localhost/testApp”将毫无问题地呈现 Home/Index。
我将范围缩小到RoutePrefix
是问题所在。 如果我删除RoutePrefix
并将默认值更改为: new { controller = "default", action = "index", id = UrlParameter.Optional }
然后“localhost/testApp”工作,但显然这需要对其他路由使用/default而不是/entry。
此外,如果我保留前缀(将默认控制器切换回“entry”)并将Route("~/")
到Index
方法,那么“localhost/testApp”也可以根据 ~ 路由的 doco 工作覆盖路由前缀。
我想知道是否有解释为什么 RoutePrefix 似乎与默认路由不兼容? 我可以为该默认操作添加 ~/ 路由,但似乎我对如何使用 RoutePrefix 缺少一些了解。
动作属性路由具有最高优先级。 如果您使用它,则只有路由属性有效,其他所有内容都将被忽略。 您可以根据需要对任意多条路线执行一项操作。
由于您有 2 个变体 - Route() 和 Route("Index") 它仅适用于 2 个 url -"localhost/testApp/entry" 和 "localhost/testApp/entry/index"。
如果您删除 Route() 它将仅适用于一个 url-lcalhost/testApp/entry/index”。
如果添加第 3 条 Route("~/") 它将适用于第 3 个 url "localhost/testApp" Sign ~ 表示应忽略任何前缀,它从 root 开始。
所以你不能在 Index action 上使用默认的常规路由,因为它只服从路由属性。
此外,您还有一个控制器 [RoutePrefix("entry")] 属性路由,它是下一个最高优先级,因此它会覆盖配置文件中的约定路由。 这就是默认路由不适用于此控制器并且它不会自动转到索引的原因。 要使默认路由工作,您需要删除路由前缀并修复 Web 配置
defaults: new { controller = "default", action = "index", id = UrlParameter.Optional }
当前的默认控制器 = "entry" 根本不存在。
因此,您有两种选择将 Index 作为默认路由操作 - 删除所有属性路由并丢失所有其他额外路由或添加更多路由。
感谢 Serge 帮助指出我对[RoutePrefix]
的错误假设。 这里的问题是[RoutePrefix]
不是控制器的替代名称(尽管这是它在表面上的行为),而是每个单独操作的前缀。 虽然 URL 中的映射将是相同的:
示例 1:
public class EntryController
{
public ActionResult Index() { ... }
}
示例 2:
[RoutePrefix("Entry")]
public class DefaultController
{
[Route("Index")]
public ActionResult Index() { ... }
}
这两个示例都将解析“localhost/testApp/entry/index”,但是只有第一个映射会被视为匹配 {controller}/{action} 并解析“entry/index”的“默认”映射。
因此,如果一个动作 /w 基于属性的路由需要成为根默认值,如果没有[RoutePrefix]
或 [Route("~/")] ,则需要使用[Route()]
将其显式声明为根如果有[RoutePrefix]
。 因为它不会包含在 {controller}/{action} 路由中。 (通过完全删除默认的 {controller}/{action} 路由来验证)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.