La guía paso a paso o código que hallarás en este artículo es la resolución más fácil y válida que encontramos a esta inquietud o problema.
Solución:
La mejor forma es utilizar ActionFilterAttribute. Le mostraré cómo usarlo en .Net Core y .Net Framework.
.Net Core 2.1 y 3.1
public class ViewBagActionFilter : ActionFilterAttribute
public ViewBagActionFilter(IOptions settings)
//DI will inject what you need here
public override void OnResultExecuting(ResultExecutingContext context)
// for razor pages
if (context.Controller is PageModel)
var controller = context.Controller as PageModel;
controller.ViewData.Add("Avatar", $"~/avatar/empty.png");
// or
controller.ViewBag.Avatar = $"~/avatar/empty.png";
//also you have access to the httpcontext & route in controller.HttpContext & controller.RouteData
// for Razor Views
if (context.Controller is Controller)
var controller = context.Controller as Controller;
controller.ViewData.Add("Avatar", $"~/avatar/empty.png");
// or
controller.ViewBag.Avatar = $"~/avatar/empty.png";
//also you have access to the httpcontext & route in controller.HttpContext & controller.RouteData
base.OnResultExecuting(context);
Entonces necesitas registrar esto en tu startup.cs.
.Net Core 3.1
public void ConfigureServices(IServiceCollection services)
services.AddControllersWithViews(options =>
options.Filters.Add();
);
.Net Core 2.1
public void ConfigureServices(IServiceCollection services)
services.AddMvc(options =>
options.Filters.Add();
);
Entonces puedes usarlo en todas las vistas y páginas.
@ViewData["Avatar"]
@ViewBag.Avatar
.Net Framework (ASP.NET MVC .Net Framework)
public class UserProfilePictureActionFilter : ActionFilterAttribute
public override void OnResultExecuting(ResultExecutingContext filterContext)
filterContext.Controller.ViewBag.IsAuthenticated = MembershipService.IsAuthenticated;
filterContext.Controller.ViewBag.IsAdmin = MembershipService.IsAdmin;
var userProfile = MembershipService.GetCurrentUserProfile();
if (userProfile != null)
filterContext.Controller.ViewBag.Avatar = userProfile.Picture;
registre su clase personalizada en el global. asax (Application_Start)
protected void Application_Start()
AreaRegistration.RegisterAllAreas();
GlobalFilters.Filters.Add(new UserProfilePictureActionFilter(), 0);
Entonces puedes usarlo en todas las vistas.
@ViewBag.IsAdmin
@ViewBag.IsAuthenticated
@ViewBag.Avatar
También hay otra forma
Creando un método de extensión en HtmlHelper
[Extension()]
public string MyTest(System.Web.Mvc.HtmlHelper htmlHelper)
return "This is a test";
Entonces puedes usarlo en todas las vistas.
@Html.MyTest()
Dado que las propiedades de ViewBag están, por definición, vinculadas a la presentación de la vista y a cualquier lógica de vista ligera que pueda ser necesaria, Crearía una WebViewPage base y establezca las propiedades en la inicialización de la página. Es muy similar al concepto de un controlador base para lógica repetida y funcionalidad común, pero para sus puntos de vista:
public abstract class ApplicationViewPage : WebViewPage
protected override void InitializePage()
SetViewBagDefaultProperties();
base.InitializePage();
private void SetViewBagDefaultProperties()
ViewBag.GlobalProperty = "MyValue";
Y luego en ViewsWeb.config
, selecciona el pageBaseType
propiedad:
No lo he probado, pero es posible que desee registrar sus vistas y luego configurar los datos de la vista durante el proceso de activación.
Debido a que las vistas se registran sobre la marcha, la sintaxis de registro no le ayuda a conectarse al Activated
evento, por lo que debe configurarlo en un Module
:
class SetViewBagItemsModule : Module
protected override void AttachToComponentRegistration(
IComponentRegistration registration,
IComponentRegistry registry)
if (typeof(WebViewPage).IsAssignableFrom(registration.Activator.LimitType))
registration.Activated += (s, e) =>
((WebViewPage)e.Instance).ViewBag.Global = "global";
;
Esta podría ser una de esas sugerencias mías del tipo “la única herramienta es un martillo”; puede haber formas más simples habilitadas para MVC para hacerlo.
Editar: Enfoque alternativo, menos código: solo conéctelo al controlador
public class SetViewBagItemsModule: 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.Config = e.Context.Resolve();
viewBag.Identity = e.Context.Resolve();
;
Edición 2: Otro enfoque que funciona directamente desde el código de registro del controlador:
builder.RegisterControllers(asm)
.OnActivated(e =>
dynamic viewBag = ((Controller)e.Instance).ViewBag;
viewBag.Config = e.Context.Resolve();
viewBag.Identity = e.Context.Resolve();
);
Te mostramos comentarios y valoraciones
Si haces scroll puedes encontrar las aclaraciones de otros administradores, tú aún tienes la libertad de dejar el tuyo si te apetece.