在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的更多相关文章

  1. ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析

    ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Core整个WCF host. 因 ...

  2. ASP.NET Core 3.0 自动挡换手动挡:在 Middleware 中执行 Controller Action

    最近由于发现奇怪的 System.Data.SqlClient 性能问题(详见之前的博文),被迫提前了向 .NET Core 3.0 的升级工作(3.0 Preview 5 中问题已被修复).郁闷的是 ...

  3. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

  4. 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] ...

  5. ASP.NET Core HTTP 管道中的那些事儿

    前言 马上2016年就要过去了,时间可是真快啊. 上次写完 Identity 系列之后,反响还不错,所以本来打算写一个 ASP.NET Core 中间件系列的,但是中间遇到了很多事情.首先是 NPOI ...

  6. 在.NET Core控制台程序中使用依赖注入

    之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ...

  7. 在ASP.NET Core使用Middleware模拟Custom Error Page功能

    一.使用场景 在传统的ASP.NET MVC中,我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常.只要某个Action设置了HandleErrorAtt ...

  8. Core 1.0中的管道-中间件模式

    ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...

  9. .NET Core 1.1日期解析无APi、SQL Server数据转换JSON

    前言 在批量导入Excel中的数据时发现出生日期为整数也就是为天数,结果倒腾了翻,这是其一,其二是数据库中的某一列存的是JSON数据,但是场景是为了作为作业来运行,此时不得不将筛选出的数据手动拼接成J ...

随机推荐

  1. VMware安装win7:units specified don't exist问题

    主要是磁盘接口不匹配,调整CD/DVD和硬件磁盘接口, CD/DVD调整成IDE,硬盘调整成SATA即可. 提示system not found,主分区没有激活,进入disgenius,会提示修正,保 ...

  2. LSTM Accuracy

    Training iter #1: Batch Loss = 1.234543, Accuracy = 0.29866665601730347PERFORMANCE ON TEST SET: Batc ...

  3. gridiew列求和,表的列求和,表的记录数,时间段查询

    下面求的是gridview中第5列的值,并在lable1中显示 protected void Page_Load(object sender, EventArgs e)    {        int ...

  4. 25-删除m位数是剩下的最大

    /*                                    寻找最大数   题目内容: 请在整数 n 中删除m个数字, 使得余下的数字按原次序组成的新数最大,比如当n=92081346 ...

  5. TokuMX唯一索引不支持dropDups选项

    TokuMX v1.5.0的唯一索引(unique index)不支持dropDups选项, 如果源数据包含相同目标key的文档,将无法建立唯一索引. 问题场景: 从MongoDB到TokuMX的数据 ...

  6. DirectFB编程

    一.简介 DirectFB是一个轻量级的提供硬件图形加速,输入设备处理和抽象的图形库,它集成了支持半透明的视窗系统以及在LinuxFramebuffer驱动之上的多层显示.它是一个用软件封装当前硬件无 ...

  7. mysql简单实现查询结果添加序列号的方法

    方法1: SELECT @rownum :=@rownum + 1 AS rownum, t.* FROM integral_system_user t, (SELECT @rownum := 0) ...

  8. POSIX systemV共享内存的区别

    POISX共享内存分为两种方式: 1.内存映射文件 特点:共享内存的改变能在文件中体现: 2.共享内存区对象 特点:共享内存的改变在文件上看不出来(实际上根本打不开该文件): 以上两者都是基于mmap ...

  9. 利用ks构建ISO中的一些坑

    构建ISO的基本流程 1.获取rpm包源码 2.将源码增量编译成二进制包 3.编写ks的包列表决定ISO制作时需要从什么地方(二进制仓库repo)取哪些二进制包 4.通过createiso命令并指定k ...

  10. 20172325 2017-2018-2 《Java程序设计》第六周学习总结

    20172325 2017-2018-2 <Java程序设计>第六周学习总结 教材学习内容总结 1.利用[ ]建立一个数组,整列数据可以通过数组名引用,数组中的每个元素则可以通过其在数组中 ...