2012-01-23 17 views
18

Esta es probablemente una pregunta tonta, pero estoy tratando de meter un objeto anónimo en ViewBag así:El almacenamiento de un objeto anónimo en ViewBag

ViewBag.Stuff = new { Name = "Test", Email = "[email protected]" }; 

y acceder a ella desde una vista de este modo:

@ ViewBag.Stuff.Name

Entiendo que ViewBag es dinámico y que "Stuff" es un objeto anónimo ... pero cuando miro con el depurador desde la línea View arriba, puedo ver todas las propiedades con los valores correctos . ¿Por qué la carpeta modelo tiene un momento tan difícil con esto?

¿Hay una buena manera de lograr esto sin crear una clase de modelo? Quiero continuar usando new {}

+1

¿Puedes usar @ ViewBag.Stuff.Name o @ ViewBag.Stuff.Email ?? Causa La prueba es un valor y no una clave/propiedad – SynerCoder

+0

Eso fue un error tipográfico y ha sido corregido. He estado tratando de acceder a las propiedades, no a sus valores. Gracias. –

+0

Resulta, esto no se puede hacer. Vea esto: http://stackoverflow.com/questions/5649536/entity-framework-select-new. – SoWeLie

Respuesta

7

Básicamente, el problema es que los tipos anónimos se generan como internos (see answer), lo que hace que las referencias duras a la propiedad del objeto sean imposibles desde la Vista. Este artículo proporciona una explicación más detallada:

http://www.heartysoft.com/anonymous-types-c-sharp-4-dynamic

Es posible lograr con el uso de una clase de contenedor dinámico Anónimo (@ respuesta de Dakill), pero pone feo rápido y debe hacer una pregunta programador por qué él/ella lo haría.

+0

Estoy buscando una respuesta sobre si se puede hacer, y si no, ¿por qué ...? (No lo voté por debajo) –

+0

Entonces, le daré otra respuesta. Sin embargo, aún mantengo esta respuesta como lo que debes hacer si estás tratando de construir una aplicación que se pueda mantener. – SoWeLie

5

Contrariamente a la creencia popular, esto se puede hacer, pero implica un hack algo feo que conducirá a problemas de mantenimiento en el futuro. Se trata de escribir una clase para "envolver" su objeto anónimo en un objeto dinámico. Lo he hecho como un ejercicio hace algún tiempo, a continuación es el código de la clase contenedora, que lo utilizaría como ViewBag.Stuff = new DynamicAnonymous(new { Name = "Test", Email = "[email protected]" }); ..

public class DynamicAnonymous : DynamicObject 
{ 
      object obj; 

      public DynamicAnonymous(object o) 
      { 
        this.obj = o; 
      } 

      public override IEnumerable<string> GetDynamicMemberNames() 
      { 
        return obj.GetType().GetProperties().Select(n => n.Name); 
      } 

      public override bool TryGetMember(GetMemberBinder binder, out object result) 
      { 
        var prop = obj.GetType().GetProperty(binder.Name); 
        if (prop == null) 
        { 
          result = null; 
          return false; 
        } 
        else 
        { 
          result = prop.GetValue(obj, null); 
          return true; 
        } 
      } 

      public override int GetHashCode() 
      { 
        return obj.GetHashCode(); 
      } 

      public override string ToString() 
      { 
        return obj.ToString(); 
      } 

      public override bool Equals(object obj2) 
      { 
        return obj.Equals(obj2); 
      }     
} 
+0

Gracias por su respuesta. +1 para proporcionar una solución alternativa. –

0

Puede hacerlo utilizando el mecanismo pueda describirse NothingsImpossible, pero la implementación de su Withou envoltorio propio usando ExpandoObject. Aquí hay un ejemplo:

var items = _repository.GetItems() 
    .Select(og => { 
     dynamic eo = new System.Dynamic.ExpandoObject(); 
     eo.Id = item.Id; 
     eo.FriendlyName = og.FriendlyName; 
     eo.Selected = itemIds.Contains(item.Id); 
     return eo; 
    }) 
    .ToArray(); 
ViewBag.Items = items; 
Cuestiones relacionadas