Access Viewbag Property for All Views

How can I access some ViewBag properties in all my views? I want to have some information, such as the current username, etc., Available everywhere, but without the need to specifically define the properties in each ActionResult method for my project

+7
asp.net-mvc razor asp.net-mvc-4
source share
4 answers

The best and most direct way to fulfill your requirement is to create a custom base controller and inherit your controller from that base controller.

public class MyBaseController : Controller { protected override void OnActionExecuting(ActionExecutingContext filterContext) { ViewBag.someThing = "someThing"; //Add whatever base.OnActionExecuting(filterContext); } } 

Now, instead of inheriting the Controller class, inherit MyBaseController in your controller, as shown: -

 public class MyOtherController : MyBaseController { public ActionResult MyOtherAction() { //Your Stuff return View(); } //Other ActionResults } 
+13
source share

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.

+15
source share

One way: create a custom attribute and then apply it globally in FilterConfig. Then you do not need to do anything in your controllers.

 public class MyCustomViewActionFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { dynamic ViewBag = filterContext.Controller.ViewBag; ViewBag.Id = "123"; ViewBag.Name = "Bob"; } } 

In App_Start/FilterConfig.cs :

  public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new MyCustomViewActionFilter()); } 

Another way if you only need user information. You can add the following to the top of your view:

 @using Microsoft.AspNet.Identity 

Then use your username using the following syntax:

 @User.Identity.GetUserName() 

You can also override the implementation of IPrincipal and provide your own properties and methods to add additional information needed for rendering.

UPDATE : view MVC 6 in Asp.Net vNext, it is actually baked in the framework. http://www.asp.net/vnext/overview/aspnet-vnext/vc#inj

+6
source share

My current solution:

Create a basic controller with all the necessary properties (very useful and appropriate).

 public abstract class BaseController : Controller { public string MyProperty { get; set; } } 

Inherits all your controllers from the base controller.

 public class MyController : BaseController { //you can read your property here } 

In your views, add this line immediately after the "@model" sentence:

 @{ BaseController ctr = ViewContext.Controller as BaseController; } 

Now you can use the property in your view, without populating the ViewBag, without having to check and distinguish ViewBag values, etc.

In a view, you can use a simple built-in expression:

 @(ctr.MyProperty) 

Or do magic logic ...

 @{ if(ctr.MyProperty == "whatelse") { //do ... } } 

Easy, fast and convenient.

0
source share

All Articles