views:

180

answers:

3

Hi folks

I have this

public class HomeController{

    public ActionResult Index()
    {
       //do stuff
       return View();
    }

Obviously this choses and renders Index.aspx in the Home folder.

What we really want is to chose another file - Index.ar.aspx - if the CurrentCulture is ar-AE. I don't want IF statements on every return View() call. Anyone help me find the best place to override the name of the view file that is selected?

Note, please don't tell me off :) I know that separate files are a bit hacky, and we ARE using RESX files, DIR directives and routes to change languages etc. But we need seperate files for layout reasons.

+2  A: 

It sounds like you really want the View engine to be able to decide which view to return, rather than having the controllers be responsible for it.

Take a look at this tutorial, and google around for some others. It's pretty simple to override the default view engine, and you can add the language choosing logic there, removing the need for it at the controller level.

womp
That's certainly a good idea if the approach leads to lots of repetitive code!
RichardOD
+2  A: 

You should create your own ViewEngine. If you are using the WebFormViewEngine that is the default one with MVC, you could easily subclass it and then override the FindView(...) method.

In your overridden FindView(...) method you could easily look for a file based on a convention that includes the name of the current culture.

Take a look at Scott Hanselmans post about a ViewEngine that looks for different view files if the site is browsed using a mobile device.

Perhaps something like:

public class ExampleViewEngine : WebFormViewEngine
{
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        ViewEngineResult result = null;
    string conventionViewName = string.Format("{0}.{1}", viewName, System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName);

    result = base.FindView(controllerContext, conventionViewName, masterName, useCache);

    if (result == null || result.View == null)
    {
        result = base.FindView(controllerContext, viewName, masterName, useCache);
    }

    return result;
    }
}
aanund
A: 
public class BaseController{
    // Don't remember parameter type exactly
    public void OnActionExecuted(ActionExecutedContext context)
    {
        // if view is returned, add culture suffix to its name
        // also may need to do so for PartialViewResult
        // One problem is if view is not named; Name is "";
        // in this case use context.ActionContext.Name or RouteData["action"] for view name
        if (context.Result is ViewResult)
        {
           var view = context.Result as ViewResult;
           view.Name = view.Name + CurrentCultureSuffix;
        }
    }
}

public class HomeController: BaseController{
    public ActionResult Index()
    {
       //do stuff
       return View();
    }
}
queen3