前言
-  《ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存》 
-  《ASP.NET Core 中的SEO优化(2):中间件中渲染Razor视图》 
背景
-  栏目的列表 -> /{父栏目名}/{子栏目名}-{页码}/
-  文章详情页 -> /{栏目名}/{文章名}.html
-  标签页 -> /{标签名}
- app.UseMvc(routes =>
 
- {
 
-     routes.MapRoute(
 
-         name: "article_list",
 
-         template: "{parentCategory}/{category}-{page}/",
 
-         defaults: new { controller = "Article", action = "Index" });
 
 
-     routes.MapRoute(
 
-         name: "article_detail",
 
-         template: "{category}/{article}.html",
 
-         defaults: new { controller = "Article", action = "Detail" });
 
 
-     routes.MapRoute(
 
-         name: "tags",
 
-         template: "{tag}/",
 
-         defaults: new { controller = "Article", action = "Tag" });
 
-     });
 
 
   原理
    - namespace Microsoft.AspNetCore.Routing
 
- {
 
-     public interface IRouter
 
-     {
 
-         Task RouteAsync(RouteContext context);
 
 
-         VirtualPathData GetVirtualPath(VirtualPathContext context);
 
-     }
 
- }
 
 
  实现
   RouteAsync
  - public async Task RouteAsync(RouteContext context)
 
- {
 
-     var requestedUrl = context.HttpContext.Request.Path.Value.TrimStart('/').ToLower();
 
-     var split = requestedUrl.Split('/');
 
 
-     if (secoend != null && secoend.EndsWith(".html") && split.Length == 2)
 
-     {
 
-         var title = secoend.Replace(".html", "");
 
-         context.RouteData.Values["controller"] = "Article";
 
-         context.RouteData.Values["action"] = "Detail";
 
-         context.RouteData.Values["category"] = first;
 
-         context.RouteData.Values["title"] = title;
 
-     }
 
-     //...对请求路径进行一系列的判断
 
 
-     //最后注入`MvcRouteHandler`示例执行`RouteAsync`方法,表示匹配成功
 
-     await context.HttpContext.RequestServices.GetService<MvcRouteHandler>().RouteAsync(context);
 
- }
 
 
   GetVirtualPath
  - public VirtualPathData GetVirtualPath(VirtualPathContext context)
 
- {
 
-     var path = string.Empty;
 
-     var hasController = context.Values.TryGetValue("controller", out var controller);
 
-     var hasAction = context.Values.TryGetValue("action", out var action);
 
-     var hasCategory = context.Values.TryGetValue("category", out var category);
 
-     var hasTitle = context.Values.TryGetValue("title", out var title);
 
 
-     if (hasController && hasAction && hasCategory && hasTitle)
 
-     {
 
-         path = $"/{category/{title}.html";
 
-     }
 
 
-     return path != string.Empty ? new VirtualPathData(this, path) : null;
 
- }
 
 
   IRouter的设置生效
  - app.UseMvc(routes =>
 
- {
 
-     //添加 自定义路由匹配与url生成组件
 
-     routes.Routes.Add(new RouteProvider());
 
- });
 
 
   相关小技巧
 -   
-   
- public static class UrlHelperExtensions
 
- {
 
-     public static string AbsoluteAction(
 
-         this IUrlHelper helper,
 
-         string actionName,
 
-         string controllerName,
 
-         object routeValues = null)
 
-     {
 
-         string scheme = helper.ActionContext.HttpContext.Request.Scheme;
 
-         return helper.Action(actionName, controllerName, routeValues, scheme);
 
-     }
 
 
-     public static string AbsoluteContent(
 
-         this IUrlHelper helper,
 
-         string contentPath)
 
-     {
 
-         return new Uri(helper.ActionContext.HttpContext.Request.GetUri(), helper.Content(contentPath)).ToString();
 
-     }
 
 
-     public static string AbsoluteRouteUrl(
 
-         this IUrlHelper helper,
 
-         string routeName,
 
-         object routeValues = null)
 
-     {
 
-         string scheme = helper.ActionContext.HttpContext.Request.Scheme;
 
-         return helper.RouteUrl(routeName, routeValues, scheme);
 
-     }
 
- }
 
 
  总结
   原文:https://yangshunjie.com/A-Middleware-Implement-For-Customized-Routing-In-AspNetCore.html
 
 .NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
