我正在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个小时里都被难过了。
答案 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
}
如果您可以使用UnitOfWorkProvider
,CreateUnitOfWork
或OpenUnitOfWork
之类的方法创建GetUnitOfWork
类,然后在控制器方法中使用它,那就更好了。如果你这样做,你将99%肯定(1%的奇怪错误),你得到适当文化的UoW。