我正在寻找类似的东西,比如设置文化的旧行为和在那之后请求中的一切都有那个文化。
类似于 ASP.NET 4.5:
Thread.CurrentThread.CurrentCulture = culture_info;
Thread.CurrentThread.CurrentUICulture = culture_info;
当我现在这样做时,一些代码似乎在 MVC 管道的不同点不断地将 Culture 重置为英语。
我为什么要那个?因为我想通过我的扩展路由逻辑在一个非常大的(和可定制的)平台类型的 Web 项目中设置文化。
默认的 RouteDataRequestCultureProvider 似乎根本不起作用 - 请参阅此处的解释:
https://irensaltali.com/en/asp-net-core-mvc-localization-by-url-routedatarequestcultureprovider/
和
本地化在通过 QueryString 设置文化时起作用,但在文化在路线中时不起作用
我不想使用作为解决方案呈现的“硬编码”url 解析,因为我的路由逻辑很复杂——不是 all 路由将在 URL 的同一位置定义文化。
我试过设置这个,但也没用:
httpContext.Features.Set<IRequestCultureFeature>(new RequestCultureFeature(request_culture, new DummyProvider()));
是否有任何解决方法可以简单为请求的其余部分设置文化?
为请求的其余部分简单设置文化的解决方法是使用默认
QueryStringRequestCultureProvider
.
这是整个演示:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddControllersWithViews()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
//...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("de"),
new CultureInfo("fr"),
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
// Formatting numbers, dates, etc.
SupportedCultures = supportedCultures,
// UI strings that we have localized.
SupportedUICultures = supportedCultures
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
创建资源文件夹并添加资源文件如下:
如下配置资源文件:
Controllers.HomeController.de.resx
Controllers.HomeController.fr.resx
参考:资源文件命名
控制器:
public class HomeController : Controller
{
private readonly IStringLocalizer<HomeController> _localizer;
public HomeController(IStringLocalizer<HomeController> localizer)
{
_localizer = localizer;
}
public IActionResult Index()
{
ViewData["Title"] = _localizer["Your Title"];
return View();
}
}
Index.cshtml:
@ViewData["Title"]
虽然我也找不到为请求的其余部分设置请求文化的方法,但您可以使用 CustomRequestCultureProvider 并使用自定义路由逻辑来设置请求的文化
app.UseRequestLocalization(options =>
{
options.AddSupportedUICultures(... set some cultures here...)
.AddSupportedCultures(... and here...)
.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
{
string cultureCode = await RunCustomRoutingAndGetCulture(context.Request);
return new ProviderCultureResult(cultureCode);
}));
});
如果您的自定义逻辑不需要等待删除异步并返回 Task.FromResult
我一直在寻找类似于 OP 在请求后设置文化的问题的解决方案。我需要在查询字符串或请求标头中检索文化字符串,@Stilgar 的回答提供了我需要的解决方案。这是他的答案的有效解决方案。它在查询字符串中提取文化键/值对。 (检查请求标头的代码被省略了。)
对于 URL 请求
https://localhost:7181/?culture=fr
,设置文化fr-FR
。在OnPost
方法中,Thread.CurrentThread.CurrentCulture
返回fr-FR
.
public void OnPost()
{
// Display the current culture
System.Diagnostics.Debug.WriteLine("Current culture is " + Thread.CurrentThread.CurrentCulture.EnglishName);
}
program.cs
app.UseRequestLocalization(options =>
{
string defaultCulture = "en-US";
string[] supportedCultures = new string[] { "fr-FR", defaultCulture };
options.AddSupportedUICultures(supportedCultures)
.AddSupportedCultures(supportedCultures)
.AddInitialRequestCultureProvider(
new CustomRequestCultureProvider(async context =>
{
string? cultureCode =
await GetCultureFromRequest(context.Request, supportedCultures) ?? defaultCulture;
return new ProviderCultureResult(cultureCode);
}));
});
static Task<string?> GetCultureFromRequest(
HttpRequest request, string[] supportedCultures)
{
if (request.QueryString.Value is null ||
!request.QueryString.Value.Contains("culture="))
{
return Task.FromResult<string?>(default);
}
string? cultureVal =
request.Query.FirstOrDefault(q => q.Key == "culture").Value;
if (cultureVal is null || string.IsNullOrEmpty(cultureVal))
{
return Task.FromResult<string?>(default);
}
string? cultureEntry = supportedCultures
.Where(c => c.Contains(cultureVal)).FirstOrDefault();
return Task.FromResult(cultureEntry ?? default);
}
上述解决方案与设置找到的本地化中间件相同here:
program.cs
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
CultureInfo[] supportedCultures = new[]
{
new CultureInfo("fr"),
};
options.DefaultRequestCulture = new RequestCulture("en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Insert(0, new QueryStringRequestCultureProvider());
});
IOptions<RequestLocalizationOptions> locOptions = builder.Services.BuildServiceProvider().GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);