为多语言ASP.NET MVC Web应用程序设置CurrentCulture的最佳位置

tug*_*erk 41 asp.net-mvc action-filter controller-factory asp.net-mvc-3

对于多语言ASP.NET MVC 3 Web应用程序,我正在确定Thread.CurrentThread.CurrentCultureThread.CurrentThread.CurrentUICulture控制器工厂,如下所示:

public class MyControllerFactory : DefaultControllerFactory {

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) {

        //Get the {language} parameter in the RouteData
        string UILanguage;
        if (requestContext.RouteData.Values["language"] == null)
            UILanguage = "tr";
        else
            UILanguage = requestContext.RouteData.Values["language"].ToString();

        //Get the culture info of the language code
        CultureInfo culture = CultureInfo.CreateSpecificCulture(UILanguage);
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;

        return base.GetControllerInstance(requestContext, controllerType);
    }

}
Run Code Online (Sandbox Code Playgroud)

上面的代码已经快一年了!所以,我愿意接受建议.

我在Global.asax文件上注册这个,如:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());
Run Code Online (Sandbox Code Playgroud)

这样做很好,但我不确定这是否是做这种行为的最佳做法和最佳场所.

我没有挖掘主要角色,ControllerFactory我无法将其与之比较ActionFilterAttribute.

你怎么看待这种行动的最佳地点?

s.e*_*ich 56

我使用了全局ActionFilter,但最近我意识到,OnActionExecuting在某些情况下,在方法中设置当前文化为时已晚.例如,当POST请求后的模型进入控制器时,ASP.NET MVC会为模型创建元数据.它发生在执行任何操作之前.因此,此时DisplayName使用默认文化处理属性值和其他数据注释内容.

最终我将当前文化设置为自定义IControllerActivator实现,它就像一个魅力.我认为从请求生命周期的角度来看,在自定义控制器工厂中托管这个逻辑几乎是一样的,就像你今天一样.它比全球使用更可靠ActionFilter.

CultureAwareControllerActivator.cs:

public class CultureAwareControllerActivator: IControllerActivator
{
    public IController Create(RequestContext requestContext, Type controllerType)
    {
        //Get the {language} parameter in the RouteData
        string language = requestContext.RouteData.Values["language"] == null ?
            "tr" : requestContext.RouteData.Values["language"].ToString();

        //Get the culture info of the language code
        CultureInfo culture = CultureInfo.GetCultureInfo(language);
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;

        return DependencyResolver.Current.GetService(controllerType) as IController;
    }
}
Run Code Online (Sandbox Code Playgroud)

Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ...
        ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new CultureAwareControllerActivator()));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • ActionFilters确实*在某些情况下*太晚了*(如果不是全部)主要是因为模型绑定(你的字符串将被转换为数字和日期以及所有)在*Action Filters之前出现*. (2认同)

Agi*_*edi 7

我知道anser已被选中.我们使用的选项是在Application的OnBeginRequest事件中初始化线程当前文化.这确保了每次请求都能发现文化

public void OnBeginRequest(object sender, EventArgs e)
{
   var culture = YourMethodForDiscoveringCulutreUsingCookie();
   System.Threading.Thread.CurrentThread.CurrentCulture = culture;
   System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
}
Run Code Online (Sandbox Code Playgroud)