Memorizzazione di un oggetto anonimo in ViewBag

Memorizzazione di un oggetto anonimo in ViewBag

In sostanza, il problema è che i tipi anonimi vengono generati come interni (vedi risposta), rendendo impossibili i riferimenti tipizzati alla proprietà dell'oggetto dalla vista. Questo articolo fornisce una spiegazione più dettagliata:

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

È possibile ottenere risultati con l'uso di una classe wrapper dinamica anonima (@risposta di Dakill), ma diventa brutta velocemente e dovrebbe far domandare a un programmatore perché lo farebbe.


Contrariamente alla credenza popolare, questo può essere fatto, ma comporta un hack alquanto brutto che porterà a problemi di manutenzione lungo la strada. Implica la scrittura di una classe per "avvolgere" il tuo oggetto anonimo in un oggetto dinamico. L'ho fatto come esercizio qualche tempo fa, di seguito è riportato il codice della classe wrapper, lo useresti come 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);
            }                
 }

possiamo realizzarlo benissimo usando Json

nel Titolare :

using Newtonsoft.Json;
ViewBag.Stuff = JsonConvert.SerializeObject(new { Name = "Test", Email = "[email protected]" });

in vista :

@using Newtonsoft.Json
<p>@JsonConvert.DeserializeObject(ViewBag.Stuff).Name</p>

Nota:questo è stato testato in Asp.Net Core 2.2, controlla quel link per installare Newtonsoft.Json