asp.net mvc strongly typed master page - problem with types

454 views Asked by At

I have two view models:

public class MasterPageViewModel
{
    public string Meta { get; set; }
}

public class Entry : MasterPageViewModel
{
    public int EntryID { get; set; }
    public string Title { get; set; }
    public DateTime PubDate { get; set; }
}

Index page returns a list of entries, so in the view contains:

...Inherits="System.Web.Mvc.ViewPage<IEnumerable<bl.Models.Entry>>"

Then the master page contains

...Inherits="System.Web.Mvc.ViewMasterPage<bl.Models.MasterPageViewModel>"

And here is the error that I am getting:

The model item passed into the dictionary is of type 'System.Linq.EnumerableQuery`1[bl.Models.Entry]', but this dictionary requires a model item of type 'bl.Models.MasterPageViewModel'.

I can easily bypass that error by using ViewData dictionary on the master page, but in my case I would prefer strongly typed approach. In future I want to be able to add lists of categories and tags that would appear on the master page.

1

There are 1 answers

1
EBarr On

I have something like the structure you describe in an MVC site I'm working on now. I haven't found a really satisfying answer -- in many cases it feels like you want two distinct models, one for the master page and one for content pages. Unfortunately, that's not how MVC works.

I've only come across one solution, other than the ViewData option you mentioned.

Base Class

  • Build a base class that all your models inherit off.
  • The base class contains all the properties you need in your master page.
  • Good: it's simple inheritance
  • Bad: you end up with wrapper methods / models for basic things like passing an enumberable collection.

So in your case you would end up with something like ...

public class MasterPageViewModel {
    public string Meta { get; set; }
}

public class Entry : MasterPageViewModel {
  public IEnumerable<bl.Models.EntryItem> Items {get; set }
}

public class EntryItem{
    public int EntryID { get; set; }
    public string Title { get; set; }
    public DateTime PubDate { get; set; }
}

And your Index page would look like...

...Inherits="System.Web.Mvc.ViewPage<bl.Models.Entry>"

It's kind of a pain in the butt because you end up with lots of little models. Once I got used to it, however, i've stopped thinking about it.

HTH,

-eric