一佳一

记录像1+1一样简洁的代码

导航

ASP.NET MVC 路由配置

Posted on 2020-01-09 10:16  一佳一  阅读(1207)  评论(0编辑  收藏  举报

首先了解下流程

 

 

 

 

 

路由源码可参考

https://referencesource.microsoft.com/#System.Web/Routing/UrlRoutingModule.cs,9b4115ad16e4f4a1

代码实际举例

配置路由

App_Start文件下,新建RouteConfig.cs文件里配置路由信息。通过静态方法RouteCollection.MapRoute()配置路由信息。

如:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//忽略该模式的URL

        routes.MapRoute(
            name: "Default",//路由名称
            url: "{controller}/{action}/{id}",//路由模板
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }//路由默认值,参数id可以为空
        );
    }
}
  • name:为该路由名称

  • url:为路由模板,{}是占位符。

  • defaults:为路由默认值

 示例

 

 

路由顺序和优先级

路由引擎在定位路由时,会遍历路由集合中的所有路由。只要发现了一个匹配的路由,会立即停止搜索。所以定义路由一定要注意路由的先后循序。一般是越是精确的放在前面

如:有一个如下的路由配置

routes.MapRoute{
    name:  "one",
    url:"{site}",
    defaults:new{controller="MyControllerOne",action="Index"}
}
routes.MapRoute{
    name:"two",
    url:"Admin",
    defaults:new {controller="Admin",action="Index"}
}

 

第一个路由有一个{site}占位符。默认的控制器为MyControllerOne。第二个路由是一个常量Admin,默认的控制器为Admin。这两个都是正确的路由配置。但是当我们输入urlxxx.com/admin时,我们预想的是请求AdminController下的Index操作方法。但是根据上面的路由映射,该url会匹配第一个路由,然后就停止了路由查找。此时触发的ControllerMyControllerOne

 

路由约束

之前的路由配置,都没有url的参数的类型信息。如果我们的Action是一个Int类型,但是url中的参数是个字符串,这样就会导致错误。所以如果有url的类型约束可以规避这个错误的发生。

在Asp.Net MVC中我们可以通过正则表达式来约束路由。

如:

routes.MapRoute{
    "Default",
    "{controller}/{action}/{id}",
    new{controller="Home",action="Index",id=UrlParameter.Optional},
    new{id="\d+"}//该id为整数
}

除了使用正则表达式来约束路由,我们还可以通过继承IRouteConstraint接口自定义约束规则

如:

public class MyRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        //获取id的值
        var id = values[parameterName];

        //id验证方法

        return true;
    }
}

更新路由配置

routes.MapRoute{
    "Default",
    "{controller}/{action}/{id}",
    new{controller="Home",action="Index",id=UrlParameter.Optional},
    new{id=new MyRouteConstraint()}
}