我刚刚开始本地化ASP.Net MVC应用程序.大多数字符串将在资源文件中定义,并通过Matt的Localization Helpers检索.其他字符串必须存储在数据库中.
我的问题:
我应该CurrentUICulture在请求管道中尽早设置并在整个应用程序中使用它,还是Request.UserLanguages[0]在需要时直接使用?
现在我想我应该CurrentUICulture在Application_BeginRequest中设置.实现看起来像这样:
protected void Application_BeginRequest(object sender, EventArgs e)
{
var cultureName = HttpContext.Current.Request.UserLanguages[0];
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureName);
}
Run Code Online (Sandbox Code Playgroud)
这是最好的地方CurrentUICulture,是Request.UserLanguages[0]获得这些信息的最佳地点吗?
更新:
Ariel的帖子让我意识到这可以在没有代码的情况下定义,使用web.config
<system.web>
<!--If enableClientBasedCulture is true, ASP.NET can set the UI culture and culture for a Web page automatically, based on the values that are sent by a browser.-->
<globalization enableClientBasedCulture="true" culture="auto:en-US" uiCulture="auto:en"/>
Run Code Online (Sandbox Code Playgroud) 我是否正确async/await本身与并发/并行无关,只不过是继续传递样式(CPS)实现?真正的线程是通过传递/恢复的SynchronizationContext实例来执行的await?
如果这是正确的,我有以下问题SynchronizationContext:
它保证在同一个线程上执行继续.
但是,是否有任何保证线程的上下文信息是持久的?我的意思是Name,CurrentPrincipal,CurrentCulture,CurrentUICulture,等它是否依赖于框架(ASP.NET,WinForms的,WCF,WPF)?
我正在使用IIS上的ASP.NET 4.6,C#,OWIN管道Microsoft.Owin.Host.SystemWeb,大量异步方法调用和标准的全局资源文件(*.resxin App_GlobalResources)创建一个简单的多语言网站.该网站使用MVC5,WebAPI2和Autofac作为依赖性解析器.
我无法正确更改生成的页面的区域设置/文化,因为异步方法每个请求使用多个线程,我找不到Thread.Current[UI]Culture为给定请求关联的每个线程设置的方法,因为这些属性未同步.我还想保持干净的代码,而没有"异步/等待文化配置"搞乱有用的代码.
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();
});
}
Run Code Online (Sandbox Code Playgroud)
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 …Run Code Online (Sandbox Code Playgroud) 我有一个Web应用程序,我使用async/await来使用大量的异步操作.一切都运行良好,但是当我创建自定义任务以并行运行多个事物时,我注意到,在此任务中,当前文化在等待之后发生了变化.问题似乎是,线程池使用操作系统的文化,这与请求的文化不同,并且默认同步不会更新文化,即使在更改任务中当前线程的文化时也是如此.
所以我创建一个自定义同步上下文:
public sealed class CulturePreservingSynchronizationContext : SynchronizationContext
{
private CultureInfo culture;
private CultureInfo cultureUI;
public CulturePreservingSynchronizationContext()
{
GetCulture();
}
public void MakeCurrent()
{
SetCulture();
SynchronizationContext.SetSynchronizationContext(CreateCopy());
}
public override SynchronizationContext CreateCopy()
{
CulturePreservingSynchronizationContext clonedContext = new CulturePreservingSynchronizationContext();
clonedContext.culture = culture;
clonedContext.cultureUI = cultureUI;
return clonedContext;
}
public override void Post(SendOrPostCallback d, object state)
{
base.Post(s =>
{
SetCulture();
d(s);
}, state);
}
public override void OperationStarted()
{
GetCulture();
base.OperationStarted();
}
private void SetCulture()
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = cultureUI; …Run Code Online (Sandbox Code Playgroud) 我想将文件发布到我的webapi.这不是问题,但是:
我希望我的行动看起来像这样:
public void Post(byte[] file)
{
}
Run Code Online (Sandbox Code Playgroud)
要么:
public void Post(Stream stream)
{
}
Run Code Online (Sandbox Code Playgroud)我想从类似的代码发布文件(当然,现在它不起作用):
<form id="postFile" enctype="multipart/form-data" method="post">
<input type="file" name="file" />
<button value="post" type="submit" form="postFile" formmethod="post" formaction="<%= Url.RouteUrl("WebApi", new { @httpRoute = "" }) %>" />
</form>
Run Code Online (Sandbox Code Playgroud)任何建议将不胜感激
根据这个问题 的答案,async/await调用应该保留CurrentCulture.就我而言,当我调用自己的异步方法时,将保留CurrentCulture.但是,如果我调用某种WCF服务方法,则不会保留CurrentCulture,它会被更改为看起来像服务器默认线程文化的东西.
我已经了解了调用托管线程的内容.它发生在每个代码行都在一个托管线程上执行(ManagedThreadId保持不变).在调用我自己的异步方法后,CultureInfo保持不变.但是当我调用WCF的方法时,ManagedTrheadId保持不变,但CurrentCulture已更改.
简化的代码如下所示::
private async Task Test()
{
// Befoe this code Thread.CurrentThread.CurrentCulture is "ru-RU", i.e. the default server's culture
// Here we change current thread's culture to some desired culture, e.g. hu-HU
Thread.CurrentThread.CurrentCulture = new CultureInfo("hu-HU");
var intres = await GetIntAsync();
// after with await Thread.CurrentThread.CurrentCulture is still "hu-HU"
var wcfres = await wcfClient.GetResultAsync();
// And here Thread.CurrentThread.CurrentCulture is "ru-RU", i.e. the default server's culture
}
private async Task<int> GetIntAsync()
{
return await Task.FromResult(1);
} …Run Code Online (Sandbox Code Playgroud) c# ×4
async-await ×3
asp.net ×1
asp.net-4.5 ×1
asp.net-mvc ×1
asynchronous ×1
conceptual ×1
cultureinfo ×1
localization ×1
owin ×1
wcf ×1