I am using the spark viewengine, asp.net mvc, and .resx files.
开发者_运维问答I want to set a language through my custom SessionModel (Session) which is registered through Castle.Windsor and has a string property of Culture which can be set by the user...
I need the current language to persist on every view, without having to constantly set the current UICulture.
Not having to do this everytime in each Controller Action:
public SessionModel SessionModel { get; set; }
public ActionResult Index()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(SessionModel.Culture);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
}
The problem with doing it this way, is if I go onto another page the current culture will flip back to the default language.
On the spark view I simply call, to obtain the current Culture:
${SR.Home}
SR.resx contains a public entry for Home.
Does anyone have a good idea of how to do this, should I do this with an ActionFilter?
Action filter seems like a good idea:
public class SetCultureActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
CultureInfo culture = FetchCultureFromContext(filterContext);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
base.OnActionExecuting(filterContext);
}
private CultureInfo FetchCultureFromContext(ActionExecutingContext filterContext)
{
throw new NotImplementedException();
}
}
and then decorate your base controller with this attribute.
I guess I am missing something. This is what I am trying to avoid (Application.cs) inside of the spark samples, I already have a custom session, it don't need to manage another, just for "culture":
the sample code:
public static string GetSessionCulture(ControllerContext controllerContext)
{
return Convert.ToString(controllerContext.HttpContext.Session["culture"]);
}
public static void SetSessionCulture(ControllerContext controllerContext, string culture)
{
controllerContext.HttpContext.Session["culture"] = culture;
}
Also after its done, how do I load the current culture for every page I have, I would have to make the call inside of HomeController Index to pull the current culture out of the session:
public object Index()
{
var user = new UserInfo
{
Name = "Frankie",
Culture = Application.GetSessionCulture(ControllerContext)
};
try
{
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(user.Culture);
}
catch
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
}
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
ViewData["user"] = user;
return View();
}
Which the only way I can come up with right now is by either creating a custom ActionFilter or creating a base Controller.
There is a much better and scalable (from a flexibility point of view) solution to this problem which has been solved if you're using the Spark View Engine.
Have a look at the sample solution here in the code base for an excellent example of how to do Internationalization or Globalization with Spark. There is absolutely no need to start doing fancy things with your ActionFilters - and this method works in MVC2 and MVC3 to allow for an easy migration if that's your future plan.
Update
In response to your other question regarding the sample in the Spark code base I think there are a few ways of skinning that cat. One way would be to keep the culture as part of the session, but in past projects where we didn't want that, we did what many website already do - we included the culture as a parameter in the route data by making sure it is included in the URL:
routes.Add(new Route("{culture}/{controller}/{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(
new { culture="en-us" action="Index", id="" }),
});
This kind of thing in combination with the Spark module I mentioned above gives you the freedom to just spend time focussing on your .resx files instead of all your time figuring out the culture and routing manually.
The fact that you have an Index.spark
and an Index.fr.spark
in the same views folder means the rest gets taken care of for you.
Hope that helps!
All the best,
Rob
精彩评论