在Controller构造函数中获取文化设置而不是默认值

时间:2013-11-28 14:09:55

标签: c# asp.net-mvc asp.net-mvc-4 localization

我正在MVC写一个多语言网站。我需要将正确的文化注入到SitesRepository中,该SiteRepository由UnitOfWork模式类实例化。

我的问题是我在构造函数中返回了错误的文化。假设回到'fr'但收到'en-GB'。

BaseController.cs - 所有控制器都从此继承。

public class BaseController : Controller
{
    protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
    {
        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 != null && Request.UserLanguages.Length > 0 ?
                    Request.UserLanguages[0] :  // obtain it from HTTP header AcceptLanguages
                    null;
        // Validate culture name
        cultureName = CultureHelper.GetImplementedCulture(cultureName); // This is safe

        // Modify current thread's cultures           
        Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

        return base.BeginExecuteCore(callback, state);
    }
}

我的ListingsController在它的构造函数中实例化了一个与文化相关的UoW / Repository模式。

public class ListingsController : BaseController
{
    // Site Filtered Data
    private SitesRepository db = null;
    private Site site = null;

    public ListingsController()
    {
        //string culture =
        //    Request.Cookies["_culture"] != null ?
        //    Request.Cookies["_culture"].Value :
        //    null;

        db = new UnitOfWork().SitesRepository;
        site = db.Site;
    }
...

我的UnitOfWork.cs:

public class UnitOfWork : IDisposable
{
    public SitesRepository SitesRepository { get; private set; }

    public UnitOfWork()
    {
        db = new PropertyInfoEntities();

        var site = GetSite();
        var culture = CultureHelper.GetCurrentCulture(); // = Thread.CurrentThread.CurrentCulture.Name;
        var language = db.Languages.Single(l => l.CultureCode == culture);
        SitesRepository = new SitesRepository(db, site, language.ID);
    }

当我在另一个控制器中使用来自ListingsController的动作时,它会返回正确的文化信息,因为BaseController.BeginExecuteCore()已经运行。 但是,当直接使用ListingsController时,它首先运行构造函数,这意味着当UoW模式尝试获取文化信息时,它总是返回en-GB而不是请求的文化。

任何有关将正确的文化融入ListingsController的UoW / Repository的最佳方法的帮助将不胜感激。我在过去的4个小时里都被难过了。

1 个答案:

答案 0 :(得分:2)

你在这里回答了自己的问题:

  

当我在另一个控制器中使用来自ListingsController的动作时,它会返回正确的文化信息,因为BaseController.BeginExecuteCore()已经运行。但是当直接使用ListingsController 时,它首先运行构造函数,这意味着当UoW模式尝试获取文化信息时,它总是返回en-GB而不是请求的文化。

因此,您必须在构造函数中创建UoW,而不是在Controller方法中。您可以创建辅助方法(或属性)来为您执行此操作:

protected SitesRepository GetRepository()
{
    if (db == null)
    {
        db = new UnitOfWork().SitesRepository;
    }

    return db;
}

然后像这样使用它:

public void SomeMethod()
{
    SiteRepository repository = GetRepository();

    // do actions with repository
}


如果您可以使用UnitOfWorkProviderCreateUnitOfWorkOpenUnitOfWork之类的方法创建GetUnitOfWork类,然后在控制器方法中使用它,那就更好了。如果你这样做,你将99%肯定(1%的奇怪错误),你得到适当文化的UoW。