受欢迎的博客标签

Asp .net Core 路由扩展点

Published
 In ASP.NET Core, you need to override TemplateRoute or implement IRouter or INamedRouter. interace INamedRouter is IRouter plus Name property. Let's create a custom route which only allows requests with url starting with/home. ,   view sourceprint? 01 public class MyTemplateRoute : TemplateRoute 02 { 03     public MyTemplateRoute(IRouter target, stringrouteTemplate, IInlineConstraintResolver inlineConstraintResolver) 04                     : base(target, 05                            routeTemplate, 06                            inlineConstraintResolver: inlineConstraintResolver) 07     { 08     } 09   10     public MyTemplateRoute(IRouter target, 11                          string routeTemplate, 12                          IDictionary<string, object> defaults, 13                          IDictionary<string, object> constraints, 14                          IInlineConstraintResolver inlineConstraintResolver) 15         : base(target, routeTemplate, defaults, constraints, inlineConstraintResolver) 16     { 17     } 18   19     public MyTemplateRoute(IRouter target, 20                          string routeName, 21                          string routeTemplate, 22                          IDictionary<string, object> defaults, 23                          IDictionary<string, object> constraints, 24                          IInlineConstraintResolver inlineConstraintResolver) 25         : base(target, routeName, routeTemplate, defaults, constraints, inlineConstraintResolver) 26     { } 27   28     public async override Task RouteAsync(RouteContext context) 29     { 30         var requestPath = context.HttpContext.Request.Path.Value ?? string.Empty; 31         if (!requestPath.StartsWith("/home", StringComparison.OrdinalIgnoreCase)) 32         { 33             return; 34         } 35         await base.RouteAsync(context); 36     } 37 }                       First of all note that MyTemplateRoute class inherits from TemplateRoute class. Next, I have overridden the RouteAsync method where I simply check whether the url starts with /home or not. If not then return otherwise call the base RouteAsync. Dead simple. Isn't? You can directly use this class in the Startup class by adding routes.Routes.Add. But it will be look more nicer and consistent if we add an extension method,   01 public static class RouteBuilderExtensions 02 { 03     public static IRouteBuilder MapRoute(this IRouteBuilder routeCollectionBuilder, 04                                          string name, 05                                          string template) 06     { 07         MapMyCustomRoute(routeCollectionBuilder, name, template, defaults: null); 08         return routeCollectionBuilder; 09     } 10   11     public static IRouteBuilder MapMyCustomRoute(this IRouteBuilder routeCollectionBuilder, 12                                          string name, 13                                          string template, 14                                          object defaults) 15     { 16         return MapMyCustomRoute(routeCollectionBuilder, name, template, defaults, constraints: null); 17     } 18   19     public static IRouteBuilder MapMyCustomRoute(this IRouteBuilder routeCollectionBuilder, 20                                          string name, 21                                          string template, 22                                          object defaults, 23                                          object constraints) 24     { 25         var inlineConstraintResolver = routeCollectionBuilder 26                                                    .ServiceProvider 27                                                    .GetService<IInlineConstraintResolver>(); 28         routeCollectionBuilder.Routes.Add(new MyTemplateRoute(routeCollectionBuilder.DefaultHandler, 29                                                             name, 30                                                             template, 31                                                             ObjectToDictionary(defaults), 32                                                             ObjectToDictionary(constraints), 33                                                             inlineConstraintResolver)); 34         return routeCollectionBuilder; 35     } 36   37   38   39     private static IDictionary<string, object> ObjectToDictionary(object value) 40     { 41         var dictionary = value as IDictionary<string, object>; 42         if (dictionary != null) 43         { 44             return dictionary; 45         } 46   47         return new RouteValueDictionary(value); 48     } 49 }                       Finally, you can use this custom route inside the Startup.cs file,    1 routes.MapMyCustomRoute( 2             name: "default", 3             template: "{controller}/{action}/{id?}", 4             defaults: new { controller = "Home", action = "Index" });                      Now only the requests with /home urls accepted by the custom route. You can find another example of custom route (which implements the IRouter class) at github. You can find the routing repository of ASP.NEt Core at here.   .