You can achieve what you want in several ways, each of which has its pros and cons.
1. With a base class
public class BaseController : Controller { protected override ViewResult View(IView view, object model) { this.ViewBag.MyProperty = "value"; return base.View(view, model); } }
PROS . It is simple enough to implement, a few lines of code, highly reusable, can be disabled at will (see comments below).
CONS : forcing all your controllers from the base class to force can have some effect, especially if you have many controllers already in place and / or you need to get them out of another base class.
2. Using the module
public class ViewBagPropertyModule: Module { protected override void AttachToComponentRegistration(IComponentRegistry cr, IComponentRegistration reg) { Type limitType = reg.Activator.LimitType; if (typeof(Controller).IsAssignableFrom(limitType)) { registration.Activated += (s, e) => { dynamic viewBag = ((Controller)e.Instance).ViewBag; viewBag.MyProperty= "value"; }; } } }
PROS : None. I know.
CONS : No. I know (except that it is a little contrary to intuition).
3. Using RegisterController Hook
builder.RegisterControllers(asm) .OnActivated(e => { dynamic viewBag = ((Controller)e.Instance).ViewBag; viewBag.MyProperty = "value"; });
PROS : Fast, Secure, Reusable: Perfect for any IoC design pattern.
CONS . Not always suitable for small projects and / or simple websites: if you do not use IoC, you often do not use RegisterController at all.
4. With the ActionFilter attribute
public class MyPropertyActionFilter : ActionFilterAttribute { public override void OnResultExecuting(ResultExecutingContext filterContext) { filterContext.Controller.ViewBag.MyProperty = "value"; } }
and then in the Global.asax.cs file:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalFilters.Filters.Add(new MyPropertyActionFilter(), 0); }
PROS . It is easy to use a less intrusive method among those mentioned.
CONS : No. I know.
I also wrote an article explaining all of the above methods.