Saltar al contenido

Establecer la propiedad ViewBag en el constructor de un controlador ASP.NET MVC Core

Revisamos de forma exhaustivamente cada escrito de nuestra web con el objetivo de enseñarte en todo momento la información más veraz y actualizada.

Solución:

Hay un problema de GitHub al respecto y se afirma que es por diseño. La respuesta que vinculó es sobre ASP.NET MVC3, la antigua pila ASP.NET heredada.

ASP.NET Core está escrito desde cero y usa diferentes conceptos, diseñados tanto para la portabilidad (múltiples plataformas) como para el rendimiento y las prácticas modernas, como el soporte integrado para la inyección de dependencia.

El último hace que sea imposible configurar ViewBag en el constructor, porque ciertas propiedades del Constructor La clase base debe inyectarse a través de Property Injection, ya que puede haber notado que no tiene que pasar estas dependencias en sus controladores derivados.

Esto significa, cuando el Controllerse llama al constructor, las propiedades para HttpContext, ControllerContext etc. no están configurados. Solo están configurados después se llama al constructor y hay una instancia / referencia válida a este objeto.

Y como se señaló en los problemas de GitHub, no se solucionará porque esto es por diseño.

Como puede ver aquí, ViewBag depende de ViewData y ViewData se llena después de que se inicializa el controlador. Si llamas ViewBag.Something = "something", luego creará una nueva instancia del DynamicViewData class, que será reemplazada por una después de que se inicialice el constructor.

Como señaló @SLaks, puede usar un filtro de acción que configura por controlador.

El siguiente ejemplo asume que usted siempre derivar sus controladores de Controller clase base.

public class BreadCrumbAttribute : IActionFilter

    private readonly string _name;

    public BreadCrumbAttribute(string name)
    
        _name = name;
    

    public void OnActionExecuting(ActionExecutingContext context)
    
        base.OnActionExecuting(context);

        var controller = context.Controller as Controller;
        if (controller != null) 
        
            controller.ViewBag.BreadcrumbCategory = _name;
        
    

Ahora deberías poder decorar tu controlador con él.

[BreadCrumb("MyCategory")]
class MyController:Controller


Tengo el mismo problema y lo resuelvo anulando el OnActionExecuted método del controlador:

    public override void OnActionExecuted(ActionExecutedContext context)
    
        base.OnActionExecuted(context);
        ViewBag.Module = "Production";
    

Aquí hay una mejor manera de hacer esto para .NET Core 3.x, use ResultFilterAttribute:

Crea tu propio filtro personalizado attribute que hereda de ResultFilterAttribute como se muestra a continuación:

   public class PopulateViewBagAttribute : ResultFilterAttribute
    


        public PopulateViewBagAttribute()
        
        

        public override void OnResultExecuting(ResultExecutingContext context)
        
            //   context.HttpContext.Response.Headers.Add(_name, new string[]  _value );
            (context.Controller as MyController).SetViewBagItems();
            base.OnResultExecuting(context);
        
    

Deberá implementar el método SetViewBagItems para completar su ViewBag

público void SetViewBagItems () ViewBag.Orders = Pedidos;

Luego decora tu clase de Controlador con el nuevo attribute:

  [PopulateViewBag]
  public class ShippingManifestController : Controller

¡Eso es todo al respecto! Si está poblando ViewBags por todas partes desde su constructor, entonces puede considerar crear una clase base de controlador con el método abstracto SetViewBagItems. Entonces solo necesita una clase ResultFilterAttribute para hacer todo el trabajo.

Comentarios y valoraciones

Agradecemos que quieras añadir valor a nuestro contenido informacional asistiendo con tu experiencia en las aclaraciones.

¡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 *