【问题标题】:ASP.NET MVC 5 Routing AreasASP.NET MVC 5 路由区域
【发布时间】:2018-05-31 15:14:52
【问题描述】:

我在 ASP.NET MVC 5 中遇到路由问题。我创建了两个区域“Public”和“Admin”,并在 url localhost/Example.WebUI 中设置了 Public/NewsController/Index 默认站点,但现在我不能使用 localhost/Example.WebUI/Admin... 我的 T4MVC 代码:

AdminAreaRegistration.cs

public class AdminAreaRegistration : AreaRegistration 
    {
        public override string AreaName 
        {
            get 
            {
                return "Admin";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context) 
        {
            context.MapRoute(
                "Admin_default",
                "Admin/{controller}/{action}/{id}",
                new { area = MVC.Admin, controller = MVC.Admin.Hierarchy.Name, action = MVC.Admin.Hierarchy.ActionNames.Index, id = UrlParameter.Optional }               
            );
        }
    }

PublicAreaRegistration.cs

 public class PublicAreaRegistration : AreaRegistration 
        {
            public override string AreaName 
            {
                get 
                {
                    return "Public";
                }
            }

            public override void RegisterArea(AreaRegistrationContext context) 
            {
                context.MapRoute(
                    "Public_default",
                    "{controller}/{action}/{id}",
                    new { controller = MVC.Public.News.Name, action = MVC.Public.News.ActionNames.Index, id = UrlParameter.Optional }
                );
            }
        }

RegistrationRoutes.cs

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { area = MVC.Public.Name, controller = MVC.Public.News.Name, action = MVC.Public.News.ActionNames.Index, id = UrlParameter.Optional },
                namespaces: new[] { "Example.WebIU.Areas.Public.Controllers" }
            );

            routes.MapRoute(
                name: "MyRoute",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = MVC.Admin.Hierarchy.Name, action = MVC.Admin.Hierarchy.ActionNames.Index, id = UrlParameter.Optional },
                namespaces: new[] { "Example.WebIU.Areas.Admin.Controllers" }
            );
        }

还有 Global.asax

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AutoMapper.Mapper.Initialize(cfg => cfg.AddProfile<AutomapperProfile>());
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
    }

你能帮帮我吗?

【问题讨论】:

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


    【解决方案1】:

    问题在于,除了Admin 区域之外,您的所有路由 URL 都完全相同。 MVC 将始终使用第一个匹配的路由并忽略后面的每个路由,因此以正确的顺序配置路由并确保该路由不匹配任何 URL (除了它应该匹配的 URL)都很重要。这个问题及其可能的解决方案最好在Why map special routes first before common routes in asp.net mvc? 中描述。

    最简单的解决方法是在 URL 中使用文字段,以确保它只匹配一组特定的 URL。

    PublicAreaRegistration.cs

    public class PublicAreaRegistration : AreaRegistration 
    {
        public override string AreaName 
        {
            get 
            {
                return "Public";
            }
        }
    
        public override void RegisterArea(AreaRegistrationContext context) 
        {
            context.MapRoute(
                "Public_default",
                "Public/{action}/{id}",
                new { controller = MVC.Public.News.Name, action = MVC.Public.News.ActionNames.Index, id = UrlParameter.Optional }
            );
        }
    }
    

    RegisterRoutes.cs

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapRoute(
            name: "MyRoute",
            url: "MyRoute/{action}/{id}",
            defaults: new { controller = MVC.Admin.Hierarchy.Name, action = MVC.Admin.Hierarchy.ActionNames.Index, id = UrlParameter.Optional },
            namespaces: new[] { "Example.WebIU.Areas.Admin.Controllers" }
        ).DataTokens["area"] = "Admin";
    
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { area = MVC.Public.Name, controller = MVC.Public.News.Name, action = MVC.Public.News.ActionNames.Index, id = UrlParameter.Optional },
            namespaces: new[] { "Example.WebIU.Areas.Public.Controllers" }
        );
    }
    

    请注意,您还以错误的顺序注册了MyRoute。这条路由必须放在Default 之前,才能完全发挥作用。如前所述,您还需要一种方法来确保并非所有 3 个分段 URL 都匹配。上面显示了使用文字段来执行此操作,但您可以使用Regex route constraintCustom route constraint 进行更高级的匹配。

    最后,您缺少将路线设置到特定区域所需的.DataTokens["area"] = "Admin"(如果您未在AdminAreaRegistration 类中定义路线,则需要这样做)。

    【讨论】:

      猜你喜欢
      • 2010-12-09
      • 2011-03-17
      • 1970-01-01
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      相关资源
      最近更新 更多