.Net Core在Middleware中解析RouteData
在ASP.Net Core中,如果直接在Middleware中获取RouteData返回的是空值,这是因为RouterMiddleware还没执行。但有些情况下需要获取RouteData,这要怎么做呢?
public async Task Invoke(HttpContext context)
{
var routeData = context.GetRouteData(); null
}
TemplateMatcher
TemplateMatcher是获取路由值的关键类。使用它可以将URL按路由Template解析成RouteData。所以我们可以使用它来获取RouteData。
下面是一个简单的辅助类供参考,如果直接使用可能会有一些性能问题,因为解析路由模板(TemplateParser.Parse(routeTemplate))需要时间,所以应当在实际使用的时候优化它:
public class RouteMatcher
{
public RouteValueDictionary Match(string routeTemplate, string requestPath)
{
var template = TemplateParser.Parse(routeTemplate);
var matcher = new TemplateMatcher(template, GetDefaults(template));
var values = matcher.Match(requestPath);
return values;
} private RouteValueDictionary GetDefaults(RouteTemplate parsedTemplate)
{
var result = new RouteValueDictionary();
foreach (var parameter in parsedTemplate.Parameters)
{
if (parameter.DefaultValue != null)
{
result.Add(parameter.Name, parameter.DefaultValue);
}
}
return result;
}
}
有了这些,就可以在Middleware里面来解析RouteData了。
注意
在解析路由时,应当按照路由的注册的先后顺序来解析,并且在成功解析时退出,这样可以保证和程序匹配时的路由是一致的。并且你应当考虑是否加上使用路由的约束(RouteConstraint)来判断当前的路由模板是否匹配。
应用场景
在纸壳CMS里面,当开启多语言时,用户访问了一个不带语言的地址,应当要自动跳转加上用户对应的语言。所以需要使用Middleware来做跳转,同时需要将用户访问的Url解析成RoteData来判断是否需要跳转。
namespace ZKEACMS.MultiLanguage
{
public class LocalizeRedirectMiddleware
{
class LocalizeRoute
{
public Easy.Mvc.Route.RouteDescriptor Descriptor { get; set; }
public TemplateMatcher TemplateMatcher { get; set; }
}
private readonly RequestDelegate _next;
private List<LocalizeRoute> _routes; public LocalizeRedirectMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
if (IsGetMethod(context) && IsSupportContentType(context))
{
IApplicationContextAccessor applicationContextAccessor = context.RequestServices.GetService<IApplicationContextAccessor>();
var setting = applicationContextAccessor.Current.CultureSetting;
if (setting.UseUrlCode(context.User.Identity.IsAuthenticated))
{
var acitveCultures = context.RequestServices.GetService<ICultureService>().GetActiveCulture();
if (_routes == null)
{
_routes = context.RequestServices.GetService<IRouteProvider>().GetRoutes().OrderByDescending(m => m.Priority).Select(m =>
{
var template = TemplateParser.Parse(m.Template);
return new LocalizeRoute
{
Descriptor = m,
TemplateMatcher = new TemplateMatcher(template, GetDefaults(template))
};
}).ToList();
}
foreach (var item in _routes)
{
var routeData = new RouteValueDictionary();
if (item.TemplateMatcher.TryMatch(context.Request.Path.Value, routeData))
{
if(item.Descriptor is LocalizeRouteDescriptor)
{
object cultureCode;
if (routeData.TryGetValue("culture", out cultureCode))
{
if (!acitveCultures.Any(m => cultureCode.Equals(m.UrlCode)))
{
context.Response.Redirect($"/{context.GetUserCulture().UrlCode}{context.Request.GetAbsoluteUrl()}");
return Task.CompletedTask;
}
}
else
{
context.Response.Redirect($"/{context.GetUserCulture().UrlCode}{context.Request.GetAbsoluteUrl()}");
return Task.CompletedTask;
}
}
break;
}
}
}
}
return _next(context);
}
private bool IsGetMethod(HttpContext context)
{
return string.Equals("GET", context.Request.Method, StringComparison.OrdinalIgnoreCase);
}
private bool IsSupportContentType(HttpContext context)
{
return true;
} private RouteValueDictionary GetDefaults(RouteTemplate parsedTemplate)
{
var result = new RouteValueDictionary(); foreach (var parameter in parsedTemplate.Parameters)
{
if (parameter.DefaultValue != null)
{
result.Add(parameter.Name, parameter.DefaultValue);
}
} return result;
}
}
}
另外
对于对于多语言的跳转,微软其实有提供了一个Localization middleware,只不过在纸壳CMS的多语言场景里有点不太适用,所以重新写了这个LocalizeRedirectMiddleware。如果你也有正在考虑多语言的解决方案,可以查看下面的链接:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.1
原文链接:http://www.zkea.net/codesnippet/detail/middleware-routedata.html
.Net Core在Middleware中解析RouteData的更多相关文章
- ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析
ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Core整个WCF host. 因 ...
- ASP.NET Core 3.0 自动挡换手动挡:在 Middleware 中执行 Controller Action
最近由于发现奇怪的 System.Data.SqlClient 性能问题(详见之前的博文),被迫提前了向 .NET Core 3.0 的升级工作(3.0 Preview 5 中问题已被修复).郁闷的是 ...
- 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制
你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...
- IDEA 之 ERROR:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]
问题描述:在使用IDEA对JSTL进行测试时出现error:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core] ...
- ASP.NET Core HTTP 管道中的那些事儿
前言 马上2016年就要过去了,时间可是真快啊. 上次写完 Identity 系列之后,反响还不错,所以本来打算写一个 ASP.NET Core 中间件系列的,但是中间遇到了很多事情.首先是 NPOI ...
- 在.NET Core控制台程序中使用依赖注入
之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ...
- 在ASP.NET Core使用Middleware模拟Custom Error Page功能
一.使用场景 在传统的ASP.NET MVC中,我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常.只要某个Action设置了HandleErrorAtt ...
- Core 1.0中的管道-中间件模式
ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...
- .NET Core 1.1日期解析无APi、SQL Server数据转换JSON
前言 在批量导入Excel中的数据时发现出生日期为整数也就是为天数,结果倒腾了翻,这是其一,其二是数据库中的某一列存的是JSON数据,但是场景是为了作为作业来运行,此时不得不将筛选出的数据手动拼接成J ...
随机推荐
- Url,HTTPUrlConnection(一)
package com.cmy.urlcon; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...
- 分割回文串 II · Palindrome Partitioning II
[抄题]: 给定一个字符串s,将s分割成一些子串,使每个子串都是回文. 返回s符合要求的的最少分割次数. [思维问题]: 不知道要用预处理字符串降低复杂度 [一句话思路]: 先把预处理获得s中回文串的 ...
- linux用户和组
1.用户隶属于用户组的. 2.用户与用户组配置文件 1)用户组配置文件 /etc/group 第一列:用户组的组名 第二列:组密码(真正的密码存储在了gshadow中) 第三列:用户组组ID,用户组唯 ...
- css设置超出部分文档隐藏(在table标签中不好使解决方案在下)
css设置: .text-over{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;cursor: pointer} div设 ...
- 为什么大神的UI设计那么高级?答案尽在此文…
对于每个网页设计师而言,在设计过程中总会碰到需要作出设计决策的时候.也许你的公司并没有全职设计师,而需求上则要求设计出全新的UI:又或者你正在制作一个你自己的个人项目,而你希望它比 Bootstrap ...
- html5之history对象理解
history对象之pushState,replaceState浏览器有一个history对象,用来保存浏览历史,用户可以通过点击浏览器的后退或前进按钮在历史记录中切换.之前对history的操作的A ...
- sklearn 算法大全
http://scikit-learn.org/stable/tutorial/machine_learning_map/
- Core Dump 程序故障分析
1.编写一个应用程序,使用gdb+core dump进行故障分析, core dump的概念: core dump又叫核心转存:当程序在运行过程中发生异常,这时Linux系统可以把程序在运行时的内存内 ...
- 2018.09.23 bzoj1076: [SCOI2008]奖励关(期望+状压dp)
传送门 一道神奇的期望状压dp. 用f[i][j]f[i][j]f[i][j]表示目前在第i轮已选取物品状态为j,从现在到第k轮能得到的最大贡献. 如果我们从前向后推有可能会遇到不合法的情况. 所以我 ...
- docker 部署nginx 使用keepalived 部署高可用
一.体系架构 在Keepalived + Nginx高可用负载均衡架构中,keepalived负责实现High-availability (HA) 功能控制前端机VIP(虚拟网络地址),当有设备发生故 ...