Derek Stegelman

Global Template Objects with .NET MVC 5

Winter in the Mountains

In modern web applications it is often convienient to have certain content or database object available to all views throughout an application. Good examples of this are avatars, usernames, and user content such as first and last names, and email addresses. Most modern web frameworks have an easy way to accomplish this. For instance, Django has middleware which can fairly easily be added to the request/response stack in order to inject objects or content into the global view/template context. This then makes it available without additional work to every template within the application.

From within the .NET space this pattern is not so straightforward and simple. Google searches did not yield official documetation on it, but there were some very helpful stack overflow answers.

In order to implement this pattern you need to define a custom ActionFilter and then register that filter within Global.asax:

UserActionFilter.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CMJobs.DAL;
using CMJobs.Models;

namespace CMJobs.Filter
{
    public class UserActionFilter : ActionFilterAttribute
    {
        private readonly IUserRepository _userRepository;

        public UserActionFilter()
        {
            CMJobsContext context = new CMJobsContext();
            this._userRepository = new UserRepository(context);
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            // Assign your content or objects to view bags here.
            User user = this._userRepository.GetOrCreateUser(filterContext.HttpContext.User.Identity.Name);

            filterContext.Controller.ViewBag.User = user;
        }
    }
}

Global.asax.cs

// Within the Application_Start() method..
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    GlobalFilters.Filters.Add(new UserActionFilter(), 0);
}