Chose to render different View (ASPX) file in ASP.NET MVC
I have this
public class HomeController{
public ActionResult Index()
{
//do stuff
return View();
}
Obv开发者_如何学编程iously 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.
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;
}
}
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.
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();
}
}
精彩评论