C# 当通过QueryString设置区域性时,本地化工作,但当区域性处于路由中时,本地化工作不起作用
这是我的路线:C# 当通过QueryString设置区域性时,本地化工作,但当区域性处于路由中时,本地化工作不起作用,c#,asp.net,.net,asp.net-core,routing,C#,Asp.net,.net,Asp.net Core,Routing,这是我的路线: app.UseMvc(routes => { routes.MapRoute( name: "defaultWithCulture", template: "{culture=fa-IR}/{controller}/{action=Index}/{id?}"); }); 但当我使用链接时,本地化是有效的: 但不是什么时候 为什么路线中的文化不适用 据我所知,asp.net核心按
app.UseMvc(routes =>
{
routes.MapRoute(
name: "defaultWithCulture",
template: "{culture=fa-IR}/{controller}/{action=Index}/{id?}");
});
但当我使用链接时,本地化是有效的:
但不是什么时候
为什么路线中的文化不适用 据我所知,asp.net核心按顺序有以下RequestCultureProviders。将使用第一个非null 您需要添加以支持路由数据中的区域性 例如:
SSA的回答并没有解决我的问题,但给了我一个很大的线索,最后我让它发挥作用 要做的是:
services.Configure<RequestLocalizationOptions>(
options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("fa-IR"),
};
options.DefaultRequestCulture = new RequestCulture(culture: "fa-IR", uiCulture: "fa-IR");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Clear();
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider();
options.RequestCultureProviders.Insert(1, new QueryStringRequestCultureProvider());
options.RequestCultureProviders.Insert(2, new CookieRequestCultureProvider());
options.RequestCultureProviders.Insert(3, new AcceptLanguageHeaderRequestCultureProvider());
services.AddSingleton(options);
});
您的路由模板应该是
模板:“{culture}/{controller}/{action=Index}/{id?}”)代码>。如何使用URL中的值来设置当前线程的区域性?@ChetanRanpariya我没有设置它。路由本身不应该这样做吗?您想要的行为在asp.net mvc core中是现成的。您可能需要编写一个操作筛选器,该筛选器将从URL中检索区域性的路由数据值,并将其设置为当前线程。@ChetanRanpariya能否将其添加为答案并演示如何操作?我以前回答过类似的问题。请参阅,如果您在该方法中遇到任何问题,请告诉我。我在多个地方看到了此解决方案,但问题是,对于我来说,我得到的错误是找不到类型或命名空间名称“RouteDataRequestCultureProvider”(您是否缺少using指令或程序集引用?)
,我找不到任何可以解决此问题的名称空间。你知道我该怎么解决吗?你需要获得Microsoft.AspNetCore.Localization.Routing包。“Microsoft.AspNetCore.Localization.Routing”:“1.1.0”我和您有相同的问题(RoutingData为空)。它是一只虫子吗?@FernandoMondo不,它不是一只虫子。这是因为本地化中间件在MVC路由器之前运行,所以它还没有对其进行解析。@MarkSzabo我认为这是一种bug或错误实现。因为这是标准的aspnet库,它不工作。谢谢你对这个话题的指导。我将创建自己的RequestCultureProvider类。那么,如果在路由之后没有调用RoutedDataRequestCultureProvider,它有什么用呢?我的意思是-我可以通过手动解析路径来使用变通方法,但我有复杂的路由规则。
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("en-GB"),
new CultureInfo("de"),
new CultureInfo("fr-FR"),
};
var options = new RequestLocalizationOptions()
{
DefaultRequestCulture = new RequestCulture(culture: "en-GB", uiCulture: "en-GB"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
};
options.RequestCultureProviders = new[]
{
new RouteDataRequestCultureProvider() { Options = options }
};
services.AddSingleton(options);
}
QueryStringRequestCultureProvider
CookieRequestCultureProvider
AcceptLanguageHeaderRequestCultureProvider
services.Configure<RequestLocalizationOptions>(
options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("fa-IR"),
};
options.DefaultRequestCulture = new RequestCulture(culture: "fa-IR", uiCulture: "fa-IR");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Clear();
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider();
options.RequestCultureProviders.Insert(1, new QueryStringRequestCultureProvider());
options.RequestCultureProviders.Insert(2, new CookieRequestCultureProvider());
options.RequestCultureProviders.Insert(3, new AcceptLanguageHeaderRequestCultureProvider());
services.AddSingleton(options);
});
public class RouteDataRequestCultureProvider : RequestCultureProvider
{
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
string culture = null;
string uiCulture = null;
uiCulture = culture = httpContext.Request.Path.Value.Split('/')[1]?.ToString();
if (culture == null)
{
return TaskCache<ProviderCultureResult>.DefaultCompletedTask;
}
var providerResultCulture = new ProviderCultureResult(culture, uiCulture);
return Task.FromResult(providerResultCulture);
}
}