Call another (localized) view based on the current culture

I use LocalizationAttribute , which implements ActionFilterAttribute to localize views. I just put [Localize] on the controller. I used LocalizeStrings.resx files to apply based on what language is in the current thread. Everything works for this simple case (with localized strings). Now I want to localize full pages (not just strings).

To implement this approach that you use?

Do I need to determine which thread is current on the controller, and based on this value for the call:

 public ActionResult AboutUs() { switch (Thread.CurrentThread.CurrentUICulture.Name) { case "en-US": return View("EnglishUSView"); case "de-DE": return View("GermanView"); default: return View(); } return View(); } 

or do you recommend something else?

+4
source share
3 answers

I would recommend just extending RazorViewEngine and overriding FindPartialView and FindView to tell ViewEngine to see if there is a view with the current culture inside the stream. If this page cannot be found, continue as usual.

  • Expand RazorViewEngine
  • In the folder "Internal view" should be (provided that the default English language). Index.cshtml and Index.de-DE.cshtml
  • Modify the Global.asax.cs file, inside the application launch you must call the localized viewing engine (the one that implements RazorViewEngine)

controller

 no further modification needed 

Views

 /Views/Home/Index.cshtml /Views/Home/Index.de.DE.cshtml 

Assistant

 public class LocalizedRazorViewEngine : RazorViewEngine { public override ViewEngineResult FindPartialView ... public override ViewEngineResult FindView... } 

Applicationstart

 ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new LocalizedRazorViewEngine()); 
+6
source

I believe that there are many ways to achieve this, but you can follow this below.

First, you can accept some kind of naming convention for views by adding a culture suffix to your names, such as ViewName_ en-US .cshtml, ViewName_ pl-PL .cshtml, etc.

If so, do not create these names in each action separately depending on the current culture. Just write the general logic that will take care of this - the base controller using the override OnActionExecuted method:

 public class BaseController : Controller { protected override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); var view = filterContext.Result as ViewResultBase; if(view != null) { var viewName = string.IsNullOrEmpty(view.ViewName) ? filterContext.RouteData.Values["action"].ToString() : view.ViewName; // retrieve the custom view name if provided or default action name otherwise var cultureName = Thread.CurrentThread.CurrentUICulture.Name; var localizedViewName = string.Format("{0}_{1}", viewName, cultureName); // construct composite, culture-aware name if (ViewExists(localizedViewName)) // safety check in case not all your views are localized - if so, just return the default name { filterContext.Result = new ViewResult { ViewName = localizedViewName }; } } } private bool ViewExists(string name) { var result = ViewEngines.Engines.FindView(ControllerContext, name, null); return result.View != null; } } 

Actions do not require localization processing right now:

 public class HomeController : BaseController { public ActionResult AboutUs() { // (...) nothing special here return View(); } } 
+2
source

Usually you apply a rule in Viewengine. This is easier than it sounds.

http://biasecurities.com/2010/01/localized-asp-net-mvc-views-using-a-localizedviewengine/

+1
source

Source: https://habr.com/ru/post/1480280/


All Articles