views:

58

answers:

1

This is a topic which has been rehashed over and over, I'm still not comfortable on how all the pieces fit together: ViewPage/ViewMasterPage, ViewPage.Model, so forth.

I've entered an undertaking where model data must be passed to both the MasterPage and the ViewPage that derives from it. The data that is passed down need not be shared between the MasterPage and ViewPage, in case that matters.

The solution I ended up with feels like a bit of a hack-job:

1. I abstracted the Controller and overrode the OnActionExecuted Method: The MasterViewPage accesses its data using ViewMasterPage.Model

    protected override void OnActionExecuted(ActionExecutedContext filterContext) {

        ViewData.Model = new CPanelViewData() { Errors = Errors, Warnings = Warnings, Notifications = Notifications };

        base.OnActionExecuted(filterContext);
    }

2. I use the Controller.View(string viewName, object model) in my Action Method: The ViewPage is made generic, ie ViewPage< FileManagerViewPage >

public class FileManagerControlPanelController : CPanelController
{
    private FileManagerViewPage viewPage = new FileManagerViewPage();

    public ActionResult AddFolder(string name, string path) {
        ...
        ...
        return View("Index", viewPage);
    }

All that being said, I wonder if this solution is legitimate. Is there a better way to serve Model data to the MasterPage and View?

A: 

For the sake of those who end up in the same situation as me, I'll elaborate on the solution I settled with.

1. I created an abstract class which represents the Master View Model.

public abstract class CpFileMgrMasterViewModel { ... }

2. I created an inherited class which represents the View Page Model.

public class CpFileMgrViewModel:CpFileMgrMasterViewModel { ... }

3. I created an abstract, generic controller which provides methods which handle the Master Model and accepts the View Model type as TModel.

public abstract class CpFileMgrController<TModel>:Controller 
    where TModel: class, new()
{
    private TModel _model = new TModel();
    public TModel Model{ get{ return _model; } }

    public CpFileMgrController() {
        ViewData.Model = _model;
    }
}

4. I placed both the Master View and View Page in to their generic form, using the two classes above:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<CpFileMgrMasterViewModel>" %>

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/....Master"
Inherits="System.Web.Mvc.ViewPage<CpFileMgrViewModel>" %>
Kivin