c# - para - Almacenar un objeto anónimo en ViewBag
viewbag c# example (4)
Contrariamente a la creencia popular, esto se puede hacer, pero implica un truco algo feo que conducirá a problemas de mantenimiento en el camino. Implica escribir una clase para "envolver" su objeto anónimo en un objeto dinámico. Lo hice como un ejercicio hace algún tiempo, a continuación se muestra el código de la clase contenedora, 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);
}
}
Esta es probablemente una pregunta tonta, pero estoy tratando de rellenar un objeto anónimo en ViewBag
así:
ViewBag.Stuff = new { Name = "Test", Email = "[email protected]" };
y acceder a él desde una vista como tal:
@ 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 de vista anterior, puedo ver todas las propiedades con los valores adecuados. ¿Por qué la carpeta de modelos tiene un tiempo tan difícil con esto?
¿Hay una buena manera de lograr esto sin crear una clase modelo? Quiero seguir usando la new {}
Esencialmente, el problema es que los tipos anónimos se generan como internos ( ver respuesta ), lo que hace que las referencias escritas 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 lograrlo con el uso de una clase de envoltorio dinámico anónimo (la respuesta de @ Dakill), pero se pone muy rápido y debería hacer una pregunta al programador por qué lo haría.
Puede hacerlo usando el mecanismo que NothingsImpossible describe, pero sin implementar su propio envoltorio 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;
podemos encantar lograr que utilizando Json
Controlador: objeto -> cadena json, Ver: cadena Json -> objeto
El scenerio es simplemente la clase del controlador serializa el objeto C # en la cadena json y luego la vista recibe esta cadena y la deserializa en un objeto, de esta manera:
en el controlador:
using Newtonsoft.Json;
ViewBag.Stuff = JsonConvert.SerializeObject(new { Name = "Test", Email = "[email protected]" });
en vista :
@using Newtonsoft.Json
<p>@JsonConvert.DeserializeObject(ViewBag.Stuff).Name</p>
Nota: esto se probó en Asp.Net Core 2.2, verifique ese enlace para instalar Newtonsoft.Json