ASP.NET Middleware doesn't preserve culture an

2019-06-21 02:07发布

问题:

Given

asp.net 4 with mvc 5.2.3 and .net 4.6.1

I want to change the CurrentCulture support globalization based on some request related things like the host.

A Owin-Middleware which sets a culture.

Simplified Version which produces the behavior:

 public override async Task Invoke(IOwinContext context)
 {
       var culture = new CultureInfo("es-ES");
       Thread.CurrentThread.CurrentCulture = culture;
       Thread.CurrentThread.CurrentUICulture = culture;

       CultureInfo.CurrentCulture = culture;
       CultureInfo.CurrentUICulture = culture;


       await Next.Invoke(context);
  }

Problem:

The Culture isn't preserved So for example a Web Controler doesn't have the culture which was set in the middleware.

This doesn't seem to be related to the thread culturepreserve issue. As when calling just some methods and awaiting them the culture is preserved.

Although with 4.5.1 it works. (I already used it this way in other projects) And when I change the httpRuntime version like this:

<httpRuntime targetFramework="4.5.1" />

everything works like a charm.

I can't find any documented breaking change for this. any hint? I can reproduce it with an empty new ASP Project Any advice?

An addition.

This problem is not related to culture preservation on thread as this works fine !

       CultureInfo.CurrentCulture = new CultureInfo("en-GB");
       await Foo();
       Debug.WriteLine(Thread.CurrentThread.CurrentCulture);// Works is en-gb
    }

    private Task Foo()
    {
        Debug.WriteLine(Thread.CurrentThread.CurrentCulture);// Works is en-gb
        return Task.FromResult(true); 
    }

回答1:

This article looks like what you need.

Are you using the app.UseRequestLocalization(); in the Configure method?

UPDATE

Have a look at this module. I've downloaded the sample and it works (you have to update some nuget packages to be able to build it.) The sample works by providing the culture in the url, but that can be configured. This works with .NET 4.6.1.



回答2:

I Opened a support case at microsoft here there reply:

Thanks for reporting the issue. we had a change in the setting the current cultures in 4.6. the change is setting the current cultures travel with the async operations. so if you set the culture during the async operation will affect the current async execution context and when the async operation is done and switch back to the original execution context, the culture will get reset to the culture in that context. you may read more about that in the like https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo(v=vs.110).aspx#Async

We still provide a way for you to get the old behavior if you want to. you can get back to the old behavior by executing the following code in the your app initialization:

static string NoAsyncCurrentCultureFlagName = @"Switch.System.Globalization.NoAsyncCurrentCulture";
AppContext.SetSwitch(NoAsyncCurrentCultureFlagName, true);