views:

128

answers:

3

Every controller class in my project derive from a base controller class, aptly named BaseController.

All view data is contained in a class named BaseViewData (which in the future could become the base controller for more specific view data classes).

I made a BaseViewData property on the BaseController since every controller requires access to the data inside the strongly-typed base view data (and the BaseController does some work to pre-populate some of the BaseViewData properties).

I did this because:

  1. If I ever changed a property, I would get compile time error checking to resolve broken code more quickly.

  2. Practicing DRY, I've managed to consolidate ALOT of code that was previously scattered throughout each controller.

However, this is the first time I've attempted to do this. So I could be overlooking a problem preparing to rear its ugly head. So:

Is making a BaseViewData class a property of a BaseController class a bad idea? If so, why?

Update 1:

My BaseController looks something like (there's more, but this should get the point across):

public class BaseController
{
  public string Language {get; set;}
  public string Locale {get; set;}
  public BaseViewData Data {get; set;}

  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    var l = (RouteData.Values["language"] != null) ? RouteData.Values["language"].ToString() : "en";
    if (l.ToLower().Contains("en"))
    {
      l = "en";
    }
    else
     l = "ja";

    Data.Language = l;
  }
}

My BaseViewData looks like this (again, there is more...):

public class BaseViewData
{
  public string Language {get;set;}
  public string Locale {get;set;}
  public bool IsOwner {get;set;}
  public string Menu1 {get;set;}
  public string Menu2 {get;set;}
  public string Menu3 {get;set;}

  public IPagedList<TYPE> ListOfTYPE {get;set;}
  etc...
}
+1  A: 

For the only site I ever worked on in ASP.NET MVC, that's exactly what we did. The nice thing about this also was that we were able to hold values in the BaseViewData class that were needed in the Master Page. Because every View had an instance of some derived BaseViewData, we could safely use the data in the BaseViewData in the Master Page.

BFree
That is exactly what I'm doing as well. Works great, just hoping I'm not preparing to raise a monster. :D
Chad
+2  A: 

The menu component of your idea may not be necessary, with the ASP.NET MVC 2 Beta you can now use Http.RenderAction to call a controller action directly from a view (such as a BuildMenu action that retrieves the menu items from the repository and returns a partialview.

See Haacked more info...

Additionally, for the simpler content such as the language / locale, this may not be necessary if you use an ASP.NET Profile Provider (accessible via both controller & view).

Mark van Proctor
Do you have an example of an ASP.NET MVC based website using a Profile Provider in this manner?
Chad
I dig the idea of being able to call an action directly through RenderAction... hmm...
Chad
I think ASP.NET MVC 2 may cause a major rewrite to my app... but could be worth it in the long run.
Chad
In terms of using the Profile Provider, there is plenty of MSDN doco on how to use it, however you don't have access to strongly typed Profile.[property name] directly in the controller. I have, however, created a ProfileCommon : ProfileBase that the default asp.net profile provider can use and allows for strongly typed access in the controller. I also build my controllers to inherit from a BaseController where I retrieve the profile using ProfileBase.Create(username) as ProfileCommon. I found these instructions on stackoverflow...
Mark van Proctor
Unfortunately, VS2010 did not ship with MVC 2 Beta, it shipped with MVC 2 Preview 2.... :( and so it does not have the Html.RenderAction methods
Mark van Proctor
VS2010 shipped? It's just in beta from the VS website.
Chad
sorry, vs2010 beta did not ship with MVC 2 beta
Mark van Proctor
+1  A: 

IMHO, you are creating a monster.

As your app grows more and more features and global screens are going to be baked into that base view model. It inevitable will be a god code-behind class like .aspx.cs files MVC tries to avoid.

Its better to use things like MVC2's RenderAction or the SubController stuff from MVC Contrib even if it means breaking the MVC pattern a little bit.

Look at a site like CNN or even Stackoverflow.com, you'll have a dozen methods in there before you know it.

jfar
Is that the only issue that you can think of? That was my primary concern as well, and one that I'll keep at the front of my mind while developing. I am the sole developer on this app, so no worries of others adding things without my knowledge ahead of time.
Chad
And, actually, even if it did become a little fat - what would be the harm in that? Is there some sort of performance hit in passing a large strongly-typed viewdata object (even if many of the properties were empty?)? Just curious... thanks.
Chad
You'd be violating the Single Responsibility Principal. Your base view model will end up being responsible for a whole lot of things.
jfar
Good point. What if all it was ever going to do is hold some data in properties? Other classes would do the "work" of creating the data to be held in the BaseViewData?
Chad