Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Master Page Data

The more I use ASP.NET MVC, the more I love it. However, in the case of showing model data on master pages there seems several ways of doing it. I am unsure as to the best solution.

My example would be a commerce site where I want to output a list of product categories on every page and also show the status of the visitors cart.

In asp.net web forms I would typically do this using user controls each doing their own databinding to retrieve the required data.

In MVC all data should be passed by the controller.

So regarding the categories the simplest solution would seem to be to pass this in View data in the controller action:

ViewData["Categories"] = _service.GetCategories();

However, doing this for every action isn't very DRY so following this article I created a base controller that adds the required data to my ViewData:

    public class AppController : Controller
{
    IAppService _service;

    public AppController() { }
    public AppController(IAppService appService)
    {
        _service = appService;
        SetSiteData();
    }

    private void SetSiteData()
    {
        ViewData["Categories"] = _service.GetCategories();
    }
}

I then created an extension for ViewMasterPage:

        public static void RenderCategoryList(this ViewMasterPage pg) {
        pg.Html.RenderPartial("CategoryList", pg.ViewData["Categories"]);
    }

And in my MasterPage:

        <div>
        <%this.RenderCategoryList(); %>
    </div>

This seems quite a clean approach. However, is this the best way as I have also seen suggestions of creating a ViewModel for your MasterPage. I could see that perhaps as your ViewModel data grows, this may be a better solution.

Regarding the cart status, I suppose I would do something similar but am unsure whether RenderAction would be more appropriate (When to use RenderAction vs RenderPartial with ASP.NET MVC). Thanks, Ben

like image 976
Ben Foster Avatar asked Jan 23 '23 16:01

Ben Foster


1 Answers

That works, although it's not the way I would do it for 2 reasons:

  1. I don't like sticking data into ViewState since you essentially cast it as object
  2. By requiring a base controller you're limiting the functionality to controllers that inherit from this basecontroller (which might not be an issue though)

I think this would be a perfect use of RenderAction (part of the MvcFutures project). This helper can be used to render an Action on another controller. So you might have a ProductController with a ListCategories action, you could just do something like:

<% Html.RenderAction<ProductController>(x => x.ListCategories()); %>

ListCategories would call

_service.GetCategories();

and might stick the info into its own Model. Then it would pass that model to the View would would be a Partial Page.

like image 121
hackerhasid Avatar answered Feb 04 '23 10:02

hackerhasid