前言
-
《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