我正在开发一个新的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")
我现在找不到在新框架中做同样事情的方法。此外,我想使用路线数据来查找我的语言,使用一些字符串函数分析我的url字符串来查找语言是不可行的。
发布于 2018-07-09 19:40:31
根据Ashley Lee的回答,这里有一种优化的方法,可以防止重复的路由配置。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// setup routes
var mvcRouter = BuildMvcRouter(app, 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 route data initialization middleware
app.Use(next => SetRouteData(next, mvcRouter));
// add localization middleware
var requestLocalizationOptions = new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US")
};
requestLocalizationOptions.RequestCultureProviders.Clear();
requestLocalizationOptions.RequestCultureProviders.Add(
new MyCustomRequestCultureProvider()
);
app.UseRequestLocalization(requestLocalizationOptions);
// add mvc routing middleware
app.UseRouter(mvcRouter);
}
这取决于必须添加到StartUp类的以下两个方法:
private static IRouter BuildMvcRouter(IApplicationBuilder app, Action<IRouteBuilder> configureRoutes)
{
if (app == null) throw new ArgumentNullException(nameof(app));
if (configureRoutes == null) throw new ArgumentNullException(nameof(configureRoutes));
app.ApplicationServices.GetRequiredService<MiddlewareFilterBuilder>().ApplicationBuilder = app.New();
var routeBuilder = new RouteBuilder(app)
{
DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>()
};
configureRoutes(routeBuilder);
routeBuilder.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices));
return routeBuilder.Build();
}
private static RequestDelegate SetRouteData(RequestDelegate next, IRouter router)
{
return async context =>
{
var routeContext = new RouteContext(context);
await router.RouteAsync(routeContext);
if (routeContext.Handler != null)
{
context.Features[typeof(IRoutingFeature)] = new RoutingFeature
{
RouteData = routeContext.RouteData
};
}
await next(context);
};
}
发布于 2020-09-01 02:18:39
随着端点路由功能的增加,这一点变得更加容易。本文将介绍如何使用端点路由功能https://aregcode.com/blog/2019/dotnetcore-understanding-aspnet-endpoint-routing/来完成此任务
var endpointFeature = context.Features[typeof(Microsoft.AspNetCore.Http.Features.IEndpointFeature)]
as Microsoft.AspNetCore.Http.Features.IEndpointFeature;
Microsoft.AspNetCore.Http.Endpoint endpoint = endpointFeature?.Endpoint;
//Note: endpoint will be null, if there was no
//route match found for the request by the endpoint route resolver middleware
if (endpoint != null)
{
var routePattern = (endpoint as Microsoft.AspNetCore.Routing.RouteEndpoint)?.RoutePattern
?.RawText;
Console.WriteLine("Name: " + endpoint.DisplayName);
Console.WriteLine($"Route Pattern: {routePattern}");
Console.WriteLine("Metadata Types: " + string.Join(", ", endpoint.Metadata));
}
https://stackoverflow.com/questions/38505184
复制相似问题