ASP.NET MVC (Async) CurrentCulture is not shared between Controller and View

删除回忆录丶 提交于 2019-12-05 01:31:22

Am I not correctly handling the CurrentCulture, or this is how it is supposed to work?

You are not. The culture of the current UI thread needs to be set before going into your async action method. If you set the culture while you are inside of an async method, it has no effect on the UI thread (as you have discovered).

But async problems aside, it is too late in the application lifecycle of MVC to be setting the culture inside of an action method, since some important culture-sensitive features of MVC (i.e. model binding) run before that point.

One way to set the culture early enough in the lifecycle is to use an authorization filter, which ensures the culture is set before model binding takes place.

using System.Globalization;
using System.Threading;
using System.Web.Mvc;

public class CultureFilter : IAuthorizationFilter
{
    private readonly string defaultCulture;

    public CultureFilter(string defaultCulture)
    {
        this.defaultCulture = defaultCulture;
    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var values = filterContext.RouteData.Values;

        string culture = (string)values["culture"] ?? this.defaultCulture;

        CultureInfo ci = new CultureInfo(culture);

        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(ci.Name);
    }
}

And to register it globally:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CultureFilter(defaultCulture: "fi-FI"));
        filters.Add(new HandleErrorAttribute());
    }
}

The above example assumes that you have setup routing to add the culture as a route value similar to this answer, but you could design a filter to get the culture from somewhere else, if desired.

NOTE: I realize this question is not about .NET Core, but as @GSerg pointed out in the comments, this same issue was reported as a bug for ASP.NET Core, and it was closed as by design. The conclusion they came to was the same:

Setting the culture inside a resource filter would apply to both the action and view.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!