2012-01-23 4 views
18

Questa è probabilmente una domanda stupida, ma sto cercando di riempire un oggetto anonimo in ViewBag in questo modo:Memorizzazione di un oggetto anonimo in ViewBag

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

e accedervi da una visualizzazione in questo modo:

@ ViewBag.Stuff.Name

Capisco che ViewBag sia dinamico e che "Stuff" sia un oggetto anonimo ... ma quando guardo con il debugger dalla riga View sopra, posso vedere tutte le proprietà con i valori corretti . Perché il modello di legatura ha un periodo così difficile con questo?

C'è un buon modo per realizzare questo senza creare una classe modello? Voglio continuare a utilizzare new {}

+1

puoi usare @ ViewBag.Stuff.Name o @ ViewBag.Stuff.Email ?? Causa Il test è un valore e non una chiave/proprietà – SynerCoder

+0

Questo era un errore di battitura ed è stato corretto. Ho cercato di accedere alle proprietà, non ai loro valori. Grazie. –

+0

Si scopre che non è possibile. Vedi questo: http://stackoverflow.com/questions/5649536/entity-framework-select-new. – SoWeLie

risposta

7

In sostanza il problema è che i tipi anonimi sono generati come interni (see answer), rendendo difficile riferimenti digitati alla proprietà dell'oggetto impossibile dalla vista. Questo articolo fornisce una spiegazione più dettagliata:

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

E 'possibile realizzare con l'uso di una classe wrapper dinamico Anonimo (@ risposta di Dakill), ma diventa brutto veloce e dovrebbe fare una domanda programmatore perché lui/lei lo farebbe.

+0

Sto cercando una risposta su se può essere fatto, e se no, perché ... (non mi ha infilato di meno) –

+0

Allora, ti darò un'altra risposta allora. Tuttavia, continuo a rispondere a questa risposta come a ciò che dovresti fare se stai cercando di creare un'applicazione gestibile. – SoWeLie

5

Contrariamente alla credenza popolare, questo può essere fatto, ma comporta un trucco un po 'brutto che porterà a problemi di manutenzione lungo la strada. Si tratta di scrivere una classe per "avvolgere" il tuo oggetto anonimo in un oggetto dinamico. Ho fatto come esercizio di qualche tempo fa, sotto è il codice per la classe wrapper, si dovrebbe utilizzare 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); 
      }     
} 
+0

Grazie per la risposta. +1 per fornire un work-around. –

0

è possibile farlo utilizzando il meccanismo descibed NothingsImpossible, ma sen za l'implementazione del proprio wrapper usando ExpandoObject. Ecco un esempio:

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;