.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 ...
随机推荐
- Our Journey of Xian Ends
Our Journey of Xian Ends https://nanti.jisuanke.com/t/18521 262144K Life is a journey, and the roa ...
- TZOJ 4839 麦森数(模拟快速幂)
描述 形如2^P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2^P-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个是P=3021377,它有9 ...
- 【C基础】之联合体
1.联合体 联合体(union)与结构体(struct)有一些相似之处.但两者有本质上的不同.在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和.而在联合体中,各成员共享一段内 ...
- python之生产者消费者模型
#Auther Bob #--*--conding:utf-8 --*-- #生产者消费者模型,这里的例子是这样的,有一个厨师在做包子,有一个顾客在吃包子,有一个服务员在储存包子,这个服务员我们就可以 ...
- Underscore模版引擎的使用-template方法
之前项目里有遇到在DOM中增加大量的html结构的时候,傻乎乎的在js中写一堆模版,然后用replace一个一个做替换.当时就是难看了点,不觉得啥,现在了解了模版引擎之后回头来看真的比较捉急了,以后是 ...
- Python和JavaScript间代码转换4个工具-乾颐堂
Python 还是 JavaScript?虽然不少朋友还在争论二者目前谁更强势.谁又拥有着更为光明的发展前景,但毫无疑问,二者的竞争在 Web 前端领域已经拥有明确的答案.立足于浏览器平台,如果放弃 ...
- [SoapUI] 设置HTTP Request的Header
import com.eviware.soapui.support.types.StringToStringMap def hearderMap = new StringToStringMap() d ...
- 分组取前N记录
分组取前N记录 经常看到问题,如何取出每组的前N条记录.方便大家参考于是便把常见的几种解法列出于下. 问题:有表 如下,要求取出各班前两名(允许并列第二)Table1+----+------+-- ...
- Winform窗体控件级权限处理
公共类: static class PowerHelper { /// <summary> /// 设置form上的组件的权限 /// ...
- windows8.1 初体验
昨天装了Win8.1,Office2013 由于是英文版的,需要装一下中文语言包,然后就能使用自带的微软拼音输入法了. 我喜欢双屏时的桌面背景,选择span时一张图片可以跨越2个屏幕,比win7的好. ...