Search code examples
.netviewmodelviewdata

Best way to CustomViewData?


What's the most practical way to add custom properties to a side wide ViewDataDictionary?

Let's assume a simple case:

public ActionResult Index()
{
  // ViewData["Title"] = "Home";
  ViewData.Title = "Home";
  return View();
}

The first thing that comes to mind is a custom class and using "new" in a application base controller:

public class CustomDataDictionary : ViewDataDictionary
{
  public string Title { get; set; }
}

public class ApplicationController : Controller
{
    public new CustomDataDictionary ViewData { get; set;} 
}

I'm assuming you would also have to also make a corresponding CustomViewPage with the same property to use the custom view data dictionary in the views as well.

The second thing that comes to mind is to create a ViewDataDictionaryExtensions class.

Thirdly, use a "View Model". My beef with View Models are that always creating one and passing it into View seems like repeating yourself over and over in controller code, at least compared to the previous two options.

The real goal is that each application might have a core set of properties in the ViewData that make sense for that apps purpose. I tend to shy away from relying on dictionary keys, and it would be nice to have real properties for other developers to rely one to know what data to set. Plus, keys can easily be misspelled.

All three methods get the job done. What have others done?


Solution

  • In the end, at least for this app, I went with having a a base AppViewModel class. Controller.OnActionExecute/ed looks to see of ViewData.Model is set and if it isn't, an instance of AppViewModel is put in it's place so all pages have a consistent Model to work with (Model.Title, Model.IsAuthenticated, Model.User, etc)

    Then more detailed controller actions have a subclass of AppModelView that gets set to ViewData.Model either manually in the action itself, or set in the OnExecute/ed via an attribute.

    Not very much code at all, but it keeps from repeating the same old create/set code in all the controller actions. And for me, it keeps the view data as a package rather than cluttering up the Controller api.