开发者

Is ViewPageBase the right place to decide what master page to load?

As you can tell from the title, I'm a n00b to MVC. I'm trying to decide what Master to load based on my route configuration settings. Each route has a masterpage property (in addition to the usual url, controller and action properties) and I'm setting the masterpage in the OnPreInit event of a ViewPageBase class (derived from ViewPage). However, I'm not sure if this is the MVC way of doing it? Do I need a controller for this that supplies the masterpage info to the view?

Here's my code snippet.

public class ViewPageBase : ViewPage
{
    protected override void OnPreInit(EventArgs开发者_开发技巧 e)
    {
        RouteElement currentRoute = MvcRoutes.GetCurrentRoute();

        //Set master page
        this.MasterPageFile = string.IsNullOrEmpty(currentRoute.MasterPage) ? 
                              MvcConfiguration.DefaultMasterPage : currentRoute.MasterPage;       

        base.OnPreInit(e);
    }

}


I'm a huge fan of ignoring anything that seems webformish and trying to always find the right MVC hook. In this case creating a custom view engine is the correct extensibility hook for this. If you think about it the engine that decides what .aspx file to render should also decide what mater page that aspx file uses. Here is some semi-psuedo ( I've never compiled it ) code that should work.

public class DynamicMasterViewEngine: VirtualPathProviderViewEngine 
{
public DynamicMasterViewEngine()
{                
 /* {0} = view name or master page name 
  * {1} = controller name      */  

 MasterLocationFormats = new[] {  
     "~/Views/Shared/{0}.master"  
 };  

 ViewLocationFormats = new[] {  
     "~/Views/{1}/{0}.aspx",  
     "~/Views/Shared/{0}.aspx"
 };  

 PartialViewLocationFormats = new[] {  
     "~/Views/{1}/{0}.ascx",               
    }; 
}

protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
    throw new NotImplementedException();
}

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{

    return new WebFormView(viewPath, masterPath );
}

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
    RouteElement currentRoute = MvcRoutes.GetCurrentRoute();

    var masterName = string.IsNullOrEmpty(currentRoute.MasterPage) ? 
                          MvcConfiguration.DefaultMasterPage : currentRoute.MasterPage;       

    return base.FindView(controllerContext, viewName, masterName, useCache);
}

protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
    return base.FileExists(controllerContext, virtualPath);
}        
}

ported from this answer

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜