加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net核心 – Asp.Net核心从url获取RouteData值

发布时间:2020-12-16 00:25:11 所属栏目:asp.Net 来源:网络整理
导读:我正在一个新的Asp.Net核心mvc应用程序。我定义了一个具有自定义约束的路由,它从URL中设置当前的应用程序文化。我想通过创建一个自定义的IRequestCultureProvider来管理我的应用程序的本地化,如下所示: public class MyCustomRequestCultureProvider : IR
我正在一个新的Asp.Net核心mvc应用程序。我定义了一个具有自定义约束的路由,它从URL中设置当前的应用程序文化。我想通过创建一个自定义的IRequestCultureProvider来管理我的应用程序的本地化,如下所示:
public class MyCustomRequestCultureProvider : IRequestCultureProvider
    {
        public Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
        {
            var language= httpContext.GetRouteValue("language");

            var result = new ProviderCultureResult(language,language);
            return Task.FromResult(result);
        }
    }

我的MyCustomRequestCultureProvider在每个请求都被击中,这是可以的。我的问题是,在MVC的管道中,我的提供者DetermineProviderCultureResult方法在路由进程之前被命中,所以httpContext.GetRouteValue(“language”)总是返回null。

在以前的MVC版本中,我可以通过这样做通过路由过程来手动处理我的url

var wrapper = new HttpContextWrapper(HttpContext.Current);
var routeData = RouteTable.Routes.GetRouteData(wrapper);
var language = routeData.GetValue("language")

我现在找不到在新框架中做同样的事情的方法。另外,我想使用路由数据找出我的langugae,用一些字符串函数分析我的url字符串,以找到语言不是一个选项。

解决方法

没有一个简单的方法来做到这一点,ASP.Net团队还没有决定实现这个功能。 IRoutingFeature仅在MVC完成请求后才可用。

我能够组建一个解决方案,这个解决方案应该适合你。这将设置您传递到UseMvc()的路由以及所有属性路由以填充IRoutingFeature。完成之后,您可以通过httpContext.GetRouteValue(“language”);.

Startup.cs

public void Configure(IApplicationBuilder app,IHostingEnvironment env,ILoggerFactory loggerFactory)
{
    // setup routes
    app.UseGetRoutesMiddleware(GetRoutes);

    // add localization
    var requestLocalizationOptions = new RequestLocalizationOptions
    {
        DefaultRequestCulture = new RequestCulture("en-US")
    };
    requestLocalizationOptions.RequestCultureProviders.Clear();
    requestLocalizationOptions.RequestCultureProviders.Add(
        new MyCustomRequestCultureProvider()
    );
    app.UseRequestLocalization(requestLocalizationOptions);

    // add mvc
    app.UseMvc(GetRoutes);
}

将路由移动到代理(用于重新使用),相同的文件/类:

private readonly Action<IRouteBuilder> GetRoutes =
    routes =>
    {
        routes.MapRoute(
            name: "custom",template: "{language=fr-FR}/{controller=Home}/{action=Index}/{id?}");

        routes.MapRoute(
            name: "default",template: "{controller=Home}/{action=Index}/{id?}");
    };

添加新的中间件:

public static class GetRoutesMiddlewareExtensions
{
    public static IApplicationBuilder UseGetRoutesMiddleware(this IApplicationBuilder app,Action<IRouteBuilder> configureRoutes)
    {
        if (app == null)
        {
            throw new ArgumentNullException(nameof(app));
        }

        var routes = new RouteBuilder(app)
        {
            DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>(),};
        configureRoutes(routes);
        routes.Routes.Insert(0,AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices));
        var router = routes.Build();

        return app.UseMiddleware<GetRoutesMiddleware>(router);
    }
}

public class GetRoutesMiddleware
{
    private readonly RequestDelegate next;
    private readonly IRouter _router;

    public GetRoutesMiddleware(RequestDelegate next,IRouter router)
    {
        this.next = next;
        _router = router;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        var context = new RouteContext(httpContext);
        context.RouteData.Routers.Add(_router);

        await _router.RouteAsync(context);

        if (context.Handler != null)
        {
            httpContext.Features[typeof (IRoutingFeature)] = new RoutingFeature()
            {
                RouteData = context.RouteData,};
        }

        // proceed to next...
        await next(httpContext);
    }
}

你可能还要定义这个类呢

public class RoutingFeature : IRoutingFeature
{
    public RouteData RouteData { get; set; }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读