【问题标题】:RouteAttribute broke my Default routeRouteAttribute 破坏了我的默认路由
【发布时间】:2017-09-14 04:43:34
【问题描述】:

如果我将 [Route(Name = "WhatEver")] 应用于操作,我将其用作默认站点路由,则在访问站点根目录时会收到 HTTP 404。

例如:

  • 创建新的示例 MVC 项目。
  • 添加属性路由:

    // file: App_Start/RouteConfig.cs
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapMvcAttributeRoutes(); // Add this line
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
    
  • 添加路由属性

    [RoutePrefix("Zome")]
    public class HomeController : Controller
    {
        [Route(Name = "Zndex")]
        public ActionResult Index()
        {
            return View();
        }
        ...
    }
    

现在,当您启动项目进行调试时,您将遇到 HTTP 错误 404。我应该如何将属性路由与默认路由映射一起使用?

【问题讨论】:

  • Index 操作使用[Route(Name = "Zndex")] 属性的目的是什么? [domain]/Zome 将自动引用[domain]/Zome/Index,使用RouteAttribute 可能需要[domain]/Zome/Zndex 才能到达Index 操作。
  • 我认为路由名称没有用于路由匹配,所以[domain]/Zome/Zndex 指向无处。我需要索引操作上的路由名称,因为我想使用带有如下路由名称的 Url 助手:<a href="@Url.RouteUrl("Zndex")">Zndex page</a>

标签: c# asp.net-mvc asp.net-mvc-5 asp.net-mvc-routing


【解决方案1】:

对于使用带有路由前缀的属性路由的默认路由,您需要将路由模板设置为空字符串。如果控制器已经有路由前缀,您还可以使用 ~/ 覆盖站点根目录。

[RoutePrefix("Zome")]
public class HomeController : Controller {
    [HttpGet]
    [Route("", Name = "Zndex")]      //Matches GET /Zome
    [Route("Zndex")]                 //Matches GET /Zome/Zndex
    [Route("~/", Name = "default")]  //Matches GET /  <-- site root
    public ActionResult Index() {
        return View();
    }
    //...
}

也就是说,当在控制器上使用属性路由时,它不再匹配基于约定的路由。控制器要么全部基于属性,要么全部基于约定,不混合。

参考Attribute Routing in ASP.NET MVC 5

【讨论】:

  • 能否请您指出任何实际说的文档,即我只能在控制器上使用属性路由或约定路由,但不能同时使用两者。你参考链接实际上说(3次)我可以在同一个项目中使用它们(但不是在同一个控制器上?)谢谢
  • @vasily.sib 跟路由注册的顺序有关。因为在基于约定的路由之前会检查属性路由,所以一旦控制器使用路由属性,它就永远不会到达基于约定的路由。即使没有匹配到属性路由。您将收到未找到的 404 错误。
  • 知道了。将[Route("~/", Name = "Zefault")] 属性添加到索引操作就可以了。然而,我实际上可以在同一个控制器中混合“属性路由”和“约定路由”,但不能在同一个动作上。在我的示例应用程序中,我可以访问 /Home/About 操作,但 /Home/Index 将返回 404。这是否记录在互联网的任何地方?非常感谢先生。 @nkosi 指出我的解决方案。
【解决方案2】:

当您启动站点时,App_Start 文件夹中的 route.config 文件中会设置一个默认路由。它看起来像这样:

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

如果您的主控制器中不再有“索引”操作,该站点会徒劳地尝试将其定位为主页并将返回 404。您可以更新您的 route.config 文件以引用新主页。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    • 2018-06-06
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    相关资源
    最近更新 更多