设置的CurrentCulture多语言ASP.NET MVC Web应用程序的最好的地方 [英] Best place to set CurrentCulture for multilingual ASP.NET MVC web applications

查看:240
本文介绍了设置的CurrentCulture多语言ASP.NET MVC Web应用程序的最好的地方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于多语言ASP.NET MVC 3 web应用程序,我确定 Thread.CurrentThread.CurrentCulture Thread.CurrentThread.CurrentUICulture 的控制器工厂如下:

 公共类MyControllerFactory:DefaultControllerFactory {    保护覆盖一个IController GetControllerInstance(System.Web.Routing.RequestContext的RequestContext,类型controllerType){        //获取的RouteData的{}语言参数
        字符串的UILanguage;
        如果(requestContext.RouteData.Values​​ [语言] == NULL)
            的UILanguage =TR;
        其他
            。的UILanguage = requestContext.RouteData.Values​​ [语言]的ToString();        //获取语言code的文化信息
        CultureInfo的文化= CultureInfo.CreateSpecificCulture(的UILanguage);
        Thread.CurrentThread.CurrentCulture =文化;
        Thread.CurrentThread.CurrentUICulture =文化;        返回base.GetControllerInstance(RequestContext的,controllerType);
    }}


  

上面code现在是近一年老了!所以,我开放的建议。


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

  ControllerBuilder.Current.SetControllerFactory(新MyControllerFactory());

这是工作不错,但我不知道这是否是最好的做法,做这类行动的最佳场所。

我没有挖成的ControllerFactory 的主体作用,我无法把它比对 ActionFilterAttribute

你觉得做这类行动的最好的地方是什么?


解决方案

我用一个全球性的 ActionFilter 这一点,但最近我意识到,设置当前文化在 OnActionExecuting 方法在某些情况下,为时已晚。例如,当POST请求后的模型涉及到控制器,ASP.NET MVC创建模型的元数据。它发生在被执行任何操作之前。其结果是,显示名称属性值等数据注解的东西使用默认的文化在这一点上的处理方式。

最后,我搬到当前区域性设置为自定义的 IControllerActivator 实施,它的工作原理就像一个魅力。我想这是从请求生命周期的角度几乎相同举办这个逻辑在自定义控制器工厂,就像你今天。它更可靠,比使用全球 ActionFilter

CultureAwareControllerActivator.cs

 公共类CultureAwareControllerActivator:IControllerActivator
{
    公众一个IController创建(RequestContext的RequestContext的,类型controllerType)
    {
        //获取的RouteData的{}语言参数
        String语言= requestContext.RouteData.Values​​ [语言] == NULL?
            TR:requestContext.RouteData.Values​​ [语言]的ToString();        //获取语言code的文化信息
        CultureInfo的文化= CultureInfo.GetCultureInfo(语言);
        Thread.CurrentThread.CurrentCulture =文化;
        Thread.CurrentThread.CurrentUICulture =文化;        返回DependencyResolver.Current.GetService(controllerType)作为一个IController;
    }
}

的Global.asax.cs

 公共类MvcApplication:System.Web.HttpApplication
{
    保护无效的Application_Start()
    {
        ...
        ControllerBuilder.Current.SetControllerFactory(新DefaultControllerFactory(新CultureAwareControllerActivator()));
    }
}

For multilingual ASP.NET MVC 3 web application, I am determining the Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture on the controller factory as follows:

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);
    }

}

The above code is nearly a year old now! So, I open for suggestions.

And I register this on the Global.asax file like:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

This is working good but I am not sure if it is the best practice and best place to do this type of action.

I haven't dug into the main role of ControllerFactory and I am unable to compare it against ActionFilterAttribute.

What do you think about the best place to do this type of action?

解决方案

I used a global ActionFilter for this, but recently I realized, that setting the current culture in the OnActionExecuting method is too late in some cases. For example, when model after POST request comes to the controller, ASP.NET MVC creates a metadata for model. It occurs before any actions get executed. As a result, DisplayName attribute values, and other Data Annotations stuff are handled using the default culture at this point.

Eventually I've moved setting the current culture to the custom IControllerActivator implementation, and it works like a charm. I suppose it's almost the same from the request lifecycle perspective to host this logic in the custom controller factory, like you have today. It's much more reliable, than usage of global 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;
    }
}

Global.asax.cs:

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

这篇关于设置的CurrentCulture多语言ASP.NET MVC Web应用程序的最好的地方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆