Asp.Net core get RouteData value from url

前端 未结 3 2013
感动是毒
感动是毒 2020-12-15 04:14

I\'m wokring on a new Asp.Net core mvc app. I defined a route with a custom constraint, which sets current app culture from the url. I\'m trying to manage localization for m

3条回答
  •  情深已故
    2020-12-15 04:49

    There isn't an easy way to do this, and the ASP.Net team hasn't decided to implement this functionality yet. IRoutingFeature is only available after MVC has completed the request.

    I was able to put together a solution that should work for you though. This will setup the routes you're passing into UseMvc() as well as all attribute routing in order to populate IRoutingFeature. After that is complete, you can access that class via 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);
    }
    

    Moved the routes to a delegate (for re-usability), same file/class:

    private readonly Action 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?}");
        };
    

    Add new middleware:

    public static class GetRoutesMiddlewareExtensions
    {
        public static IApplicationBuilder UseGetRoutesMiddleware(this IApplicationBuilder app, Action configureRoutes)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }
    
            var routes = new RouteBuilder(app)
            {
                DefaultHandler = app.ApplicationServices.GetRequiredService(),
            };
            configureRoutes(routes);
            routes.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices));
            var router = routes.Build();
    
            return app.UseMiddleware(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);
        }
    }
    

    You may have to define this class as well...

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

提交回复
热议问题