Asp.net Vnext Routing
概述
本文已经同步到《Asp.net Vnext 系列教程 》中]
ASP.NET 路由系统是主要负责两个操作:
它将传入的 HTTP 请求映射到路由处理程序给出的路由的集合。
路由系统的责任是找到匹配的路由,创建路由数据,并将请求分配给一个处理程序。
选择动作是 MVC 的处理程序的实现细节。它使用路由数据和从传入请求其他信息来选择要执行的操作
代码实现TemplateRoute 类初始化路由和 URL 模板
public class MyTemplateRoute : TemplateRoute { public MyTemplateRoute(IRouteBuilder routeCollectionBuilder) : base(routeCollectionBuilder.DefaultHandler, "{controller}/{action}/{id?}", new RouteValueDictionary(new { controller = "Home", action = "Index" }), new RouteValueDictionary(new { }), new RouteValueDictionary(new { }), routeCollectionBuilder.ServiceProvider.GetService<IInlineConstraintResolver>()) { } public override Task RouteAsync(RouteContext context) { return base.RouteAsync(context); } }
启动类
public class Startup { // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } public void Configure(IApplicationBuilder app) { app.UseMvc(routes => { //加入模板 默认http://http://localhost/Home/Index routes.Routes.Add(new MyTemplateRoute(routes)); }); } }
实现IRouter添加默认路由
public class DefaultRoute : IRouter { private readonly IRouter _next; public DefaultRoute(IRouter next) { _next = next; } public VirtualPathData GetVirtualPath(VirtualPathContext context) { return _next.GetVirtualPath(context); } public async Task RouteAsync(RouteContext context) { var oldRouteData = context.RouteData; var newRouteData = new RouteData(oldRouteData); newRouteData.Routers.Add(_next); newRouteData.Values["controller"] = "Home"; newRouteData.Values["action"] = "Index"; try { context.RouteData = newRouteData; await _next.RouteAsync(context); } finally { if (!context.IsHandled) { context.RouteData = oldRouteData; } } } }
public void Configure(IApplicationBuilder app) { app.UseMvc(routes => { //加入模板 默认http://http://localhost/Home/Index // routes.Routes.Add(new MyTemplateRoute(routes)); routes.MapRoute("default", "{controller}/{action}"); //加入路由处理 默认http://http://localhost/Home/Index routes.Routes.Add(new DefaultRoute(routes.DefaultHandler)); }); }
实现IRouteConstraint约束
public class DateConstraint : IRouteConstraint { public bool Match(HttpContext httpContext, IRouter route, string routeKey, IDictionary<string, object> values, RouteDirection routeDirection) { return values["controller"] == "Home"; } }
public void Configure(IApplicationBuilder app) { app.UseMvc(routes => { //加入模板 默认http://http://localhost/Home/Index // routes.Routes.Add(new MyTemplateRoute(routes)); //routes.MapRoute("default", "{controller}/{action}"); ////加入路由处理 默认http://http://localhost/Home/Index //routes.Routes.Add(new DefaultRoute(routes.DefaultHandler)); //加入约束 routes.MapRoute(name: "TestRoute", template: "{*constraints}", defaults: new { controller = "Home", action = "Index" }, constraints: new { constraint = new DateConstraint() }); }); }
路由特性
public class HomeController : Controller { //PUT http://localhost/AB [AcceptVerbs("PUT", Route = "AB")] // Patch http://localhost/AB [HttpPatch("AB")] //PUT http://localhost/Home/AB [AcceptVerbs("PUT", Route = "Home/AB")] //Patch http://localhost/Home/AB [HttpPatch("Home/Ab")] // ABC 动作 可以被以下地址访问 //PUT http://localhost/AB // Patch http://localhost/AB //PUT http://localhost/Home/AB //Patch http://localhost/Home/AB public IActionResult ABC() { return Content("1"); } } }
RouteConstraintAttribute 路由约束
public class CountrySpecificAttribute : RouteConstraintAttribute { public CountrySpecificAttribute(string countryCode) : base("country", countryCode, blockNonAttributedActions: true) { } }
应用在控制上
添加路由条目
routes.MapRoute( "products", "Products/{country}/{action}", defaults: new { controller = "Products" })yu
运行截图
Area
//区域名
[Area("Admin")]
//路由 [Route("[area]/Users")] public class UserManagementController : Controller { [HttpGet("All")] public IActionResult ListUsers() { return Content("11"); } }
添加路由条目
routes.MapRoute("areaRoute", "{area:exists}/{controller}/{action}", new { controller = "Home", action = "Index" });