背景
我正在使用ASP.NET 4.6、C#、OWIN管道和IIS (Microsoft.Owin.Host.SystemWeb
)创建一个简单的多语言网站,它有许多异步方法调用和标准的全局资源文件(App_GlobalResources
中的*.resx
)。该网站使用MVC5、WebAPI2和Autofac作为依赖项解析器。
问题
由于异步方法使用每个请求的多个线程,我无法正确更改生成页面的区域设置/文化,因为我找不到一种方法来为与给定请求相关联的每个线程设置Thread.Current[UI]Culture
,因为这些属性不是同步的。我还希望保持干净的代码,而不是将“async/await culture configuration”混淆在有用的代码中。
代码
Startup.cs
public void Configuration(IAppBuilder app)
{
...
app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
app.UseAutofacWebApi(httpConfiguration);
app.UseWebApi(httpConfiguration);
...
app.Use(async (ctx, next) =>
{
/* in production, detect based on current URL and/or cookie */
var culture = new CultureInfo("pl_PL");
CultureInfo.CurrentCulture = CultureInfo.CurrentUICulture = culture;
await next.Invoke();
});
}
SampleController.cs
public async Task<ActionResult> SayHello()
{
// returns pl_PL message
var msgA = Resources.Messages.HelloWorld;
await someService.doSthAsync();
// returns system default (en_US) message
var msgB = Resources.Messages.HelloWorld;
return Content(msgA + " - " + msgB);
}
- 我是否应该根据这个StackOverflow答案的建议创建一个自定义
[AspNet]SynchronizationContext
?如果是这样,我应该如何做? - 我是否应该放弃使用全局资源作为翻译源,转而使用其他方法?如果是,我可以使用什么(库)?
SampleController
继承自 Controller 类,因此你可以从那里获取当前的 HTTP 上下文和文化。 - Paulo Morgado