欧美大地,偷窥软件,李桓个人资料
在asp.net core中,如果直接在middleware中获取routedata返回的是空值,这是因为routermiddleware还没执行。但有些情况下需要获取routedata,这要怎么做呢?
public async task invoke(httpcontext context) { var routedata = context.getroutedata(); null }
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。如果你也有正在考虑多语言的解决方案,可以查看下面的链接:
原文链接:
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Net Core Web Api项目与在NginX下发布的方法
asp.net core3.1 引用的元包dll版本兼容性问题解决方案
IdentityServer4实现.Net Core API接口权限认证(快速入门)
ASP.NET Core MVC通过IViewLocationExpander扩展视图搜索路径的实现
网友评论