ASP.NET MVC 在RouteConfig.cs中添加Area路由

这个礼拜在维护公司一款老的MVC项目时,突然发现在访问非首页部分以外的其他控制器时,总是返回404,无法匹配到正确的Controller。

 根据项目主要结构还原的Demo大致如下:

 项目中一共包含三个区域,其中Admin和Wap的路由规则大致如下:

context.MapRoute(
    "Admin_default",
    "Admin/{controller}/{action}/{id}",
    new { action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
    "Wap_default",
    "Wap/{controller}/{action}/{id}",
    new { action = "Index", id = UrlParameter.Optional }
);

只有当输入完整的URL时(例如 wap/home/index/1),才会正确的匹配到相应的Controller,否则返回的都是404。而Web下的Controller则始终都可以访问,因此推测是路由规则的问题。

打开Web下的AreaRegistration类,发现有这么一段代码:

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

404的原因显然是因为匹配到了这条路由规则。例如,当请求 wap/home/index 时,将wap当做controller,home当做action,index当做id,在Web区域下自然无法匹配到相应的controller。

尝试把这条路由注释以后,wap/home/index果然可以适配到相应的action了。

这条路由的用途也很明显,就是希望提供一个默认的匹配规则,把它注释掉肯定是不合适的。而如果直接修改路由规则,又很可能对项目中其他访问了Web下controller的代码产生影响。

路由的匹配是根据其注册时的先后顺序进行的,因此只要降低这条默认规则的“优先级”即可。

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

打开Global.asax文件,可以发现注册区域路由的方法(AreaRegistration.RegisterAllAreas)位于RouteConfig.RegisterRoutes(RouteTable.Routes)之前。

因此,这里可以将Default移到RouteConfig.cs中进行注册,降低Default的注册顺序。这样,当在尝试匹配所有的区域路由无果后,才会去匹配这个默认的路由规则了。

但在注册路由时,需要通过namespaces参数来指定当满足规则,希望在哪些命名空间下进行控制器的匹配,否则如果项目中存在同名的控制器时,将会导致以下错误:

 除此之外,由于控制器和视图是在区域中创建的,因此在注册路由时,还需要通过DataTokens来设置区域名称,否则匹配到的视图很可能是非预期的,或者会发生以下的错误:

完整代码如下:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[] { "WebApplication1.Areas.Web.*" }
        ).DataTokens["area"] = "Web";
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值