设置多语言ASP当前文化的最佳位置.NET MVC web应用程序



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

上面的代码现在已经快一年了!

我把这个注册到全局。Asax文件:

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

这工作很好,但我不确定这是否是最好的做法和最好的地方做这种类型的行动。

我没有深入研究ControllerFactory的主要作用,我无法将其与ActionFilterAttribute进行比较。

你认为在哪里做这类行动最好?

我为此使用了全局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;
    }
}

Global.asax.cs :

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

我知道答案已经被选中了。我们使用的选项是在应用程序的OnBeginRequest事件中初始化线程当前文化。这确保在每个请求

时都能发现区域性。
public void OnBeginRequest(object sender, EventArgs e)
{
   var culture = YourMethodForDiscoveringCulutreUsingCookie();
   System.Threading.Thread.CurrentThread.CurrentCulture = culture;
   System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
}

放置这些代码的另一个地方是将该代码放在自定义ActionFilter的onactionexecution方法中,该方法可以在GlobalFilters集合中注册:

http://weblogs.asp.net/gunnarpeipman/archive/2010/08/15/asp-net-mvc-3-global-action-filters.aspx

代替覆盖OnActionExecuting,你可以在这里覆盖Initialize,像这样

protected override void Initialize(RequestContext requestContext)
{
        string culture = null;
        var request = requestContext.HttpContext.Request;
        string cultureName = null;
        // Attempt to read the culture cookie from Request
        HttpCookie cultureCookie = request.Cookies["_culture"];
        if (cultureCookie != null)
            cultureName = cultureCookie.Value;
        else
            cultureName = request.UserLanguages[0]; // obtain it from HTTP header AcceptLanguages
        // Validate culture name
        cultureName = CultureHelper.GetValidCulture(cultureName); // This is safe
        if (request.QueryString.AllKeys.Contains("culture"))
        {
            culture = request.QueryString["culture"];
        }
        else
        {
            culture = cultureName;
        }
        Uitlity.CurrentUICulture = culture;
        base.Initialize(requestContext);
    }

如果你不使用ControllerActivator,可以使用BaseController类并从它继承。

public class BaseController : Controller
{
    public BaseController()
    {
          //Set CurrentCulture and CurrentUICulture of the thread
    }
}

public class HomeController: BaseController    
{
    [HttpGet]
    public ActionResult Index()
    {
        //..............................................
    }
}

最新更新