Populating common view model attributes

In many ASP.Net MVC based applications, we often find ourselves needing to include the same information in every page.  Such information typically includes details of the current user, maybe environmental values and running totals like the number of items in a shopping basket.

In order to ensure these values are always available in views, base your view models on a common base class, and populate these base values using an action filter.

public class ViewModelBase
{
   public string UserName { get; set; }
   public List<UserFavorite> UserFavorites { get; set; }
   public ShoppingBasket ShoppingBasket { get; set; }
}

Then, create an action filter to populate this, if it has not already been populated by the action method on which it has been applied.

// Populates View Model base properties, if they are not already populated by the controller
class ViewModelAttribute : ActionFilterAttribute
{
   public override void OnActionExecuted(ActionExecutedContext filterContext)
   {
   ViewModelBase viewModel;

   if (filterContext.Controller.ViewData.Model == null)
   {
      viewModel = new ViewModelBase();
      filterContext.Controller.ViewData.Model = viewModel;
   }
   else
   {
      viewModel = filterContext.Controller.ViewData.Model as ViewModelBase;
   }

   if (viewModel != null)
   {
      viewModel.UserName = lookupUserName();
      viewModel.UserFavorites = GetUserFavorites();
      viewModel.ShoppingBasket = GetShoppingBasket();
   }

   base.OnActionExecuted(filterContext);
   }
}

The code first checks for a null model and assigns a base view model if none exists.  It then checks that if a model does already exist, that it is of type ViewModelBase.  If so, the appropriate values are initialized.

Then, on any action method that required this – or (in my case) at the controller level of a base controller class, add the attribute:

[ViewModel]
public abstract class ControllerBase : Controller
{
 /// Controller base

}

tim has written 12 articles

One thought on “Populating common view model attributes

  1. Eric Nelson says:

    Why not do this in OnActionExecuting() so the controller has the benefit of the stuff you’ve figured out here? Just curious…
    Thanks,
    Eric

Comments are closed.