当前位置: 移动技术网 > IT编程>开发语言>.net > .Net Core在Middleware中解析RouteData

.Net Core在Middleware中解析RouteData

2018年09月13日  | 移动技术网IT编程  | 我要评论

欧美大地,偷窥软件,李桓个人资料

在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。如果你也有正在考虑多语言的解决方案,可以查看下面的链接:

原文链接:

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网