在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. 运行 命令框不记录打过的命令,重启后CMD里面是空的.上次打过的命令消失了.

    问题: 常要用到PING命令.在cmd中输入ping 202.103.44.150 /t (这是当地的电信DNS) 用这个查看网络是不是正常.正常情况下次点开始运行的时候,运行命令框中应该 会有上次打 ...

  2. 安卓机在按HOME键时,UNITY触发的APPLICATION_PAUSE事件

    安卓机在按HOME键时,UNITY触发的APPLICATION_PAUSE事件 此时安卓程序会返回,在这一瞬间,程序可以通过SOCKET发送数据包给服务器告知, 经测试在这短暂的时间内,这个数据包能发 ...

  3. ECMAScript5新特性之获取对象特有的属性

    'use strict'; // 父类 function Fruit(){ } Fruit.prototype.name = '水果'; // 子类 function Apple(desc){ thi ...

  4. phpcms与discuz的ucenter整合

    1.安装phpcms系统,域名为pc.me   2.安装discuz,并选择安上uc_server,域名为dz.me   3.在phpcms下phpsso的系统设置   4.到ucenter管理中心- ...

  5. samba配置(z)

    http://www.cnblogs.com/mchina/archive/2012/12/18/2816717.html

  6. macos修改vmware Fusion的NAT网络

    https://blog.csdn.net/zhishengqianjun/article/details/77046796 http://pubs.vmware.com/fusion-5/index ...

  7. 子类覆写的变量被private隐藏,强制转换方式通过子类访问父类的被覆写变量:

    import static java.lang.System.*; public class SuperParent{ public static void main(String[] args){ ...

  8. nfs文件系统在linux下挂载不上的解决办法

      标签: mount nfs export 2014年08月07日 18:46:247472人阅读 评论(0) 收藏 举报  分类: 文件系统(10)  版权声明:本文为博主原创文章,未经博主允许 ...

  9. WCF TOOL CODE

    .HTML <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WCFTool. ...

  10. 函数数组demo

    #include <stdio.h> #include <string.h> typedef int(*service_func)(char *,char *); struct ...