Saltar al contenido

¿Cómo configurar las propiedades de ViewBag para todas las vistas sin usar una clase base para controladores?

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *