user1765862
user1765862

Reputation: 14155

Call different (localized) view based on current culture

I'm using LocalizationAttribute which implements ActionFilterAttribute to localize views. I simply put [Localize] on controller. I was using LocalizeStrings.resx files to apply based on which language is on current thread. Everything works for this simple case (with localized strings). Now I want to localize complete pages (not just strings).

To acomplish this which approach do you use?

Do I need to identify which thread is current on controller and based on that value to call view:

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 ?

Upvotes: 4

Views: 2162

Answers (3)

jwaliszko
jwaliszko

Reputation: 17064

I believe there are numerous ways to achieve this but you can follow this one below.

Firstly you can assume some naming convention for the views, by adding culture suffix to their names i.e. ViewName_en-US.cshtml, ViewName_pl-PL.cshtml, etc.

If so, don't construct these names in each action separately based on the current culture. Just write common logic which takes care of that - base controller with overriden 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 don't require any localization handling right now:

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

Upvotes: 2

BobRock
BobRock

Reputation: 3467

I would recommend to simply extended RazorViewEngine and override FindPartialView and FindView in order to inform ViewEngine to look is there view with current culture inside thread. If that page cannot be found than proceed as usuall.

  1. Extend RazorViewEngine
  2. Inside View folder there should be (assuming that english is default lang.) Index.cshtml and Index.de-DE.cshtml
  3. Modify Global.asax.cs file, inside application start you should call localized view engine (the one which implements RazorViewEngine)

Controller

no further modification needed

Views

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

Helper

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

ApplicationStart

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new LocalizedRazorViewEngine());

Upvotes: 7

Mathias F
Mathias F

Reputation: 15901

You would usually implement the rule in a Viewengine. Its easier than it sounds.

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

Upvotes: 1

Related Questions