2013-02-15 18 views
87

Come funziona l'ASP.NET MVC ViewBag? MSDN dice che è solo uno Object, che mi intriga, in che modo funzionano le proprietà "Magic" come ViewBag.Foo e le stringhe magiche ViewBag["Hello"]?Come funziona ViewBag in ASP.NET MVC

Inoltre, come posso crearne uno e usarlo nella mia app ASP.NET WebForms?

Gli esempi sarebbero molto apprezzati!

+0

Il concetto doesn' Sembra che sia necessario in WebForms dato che la pagina ha già accesso diretto alle variabili nel suo codice dietro il file. Mentre in MVC la vista non ha accesso a nulla nel controller oltre ai dati che vengono trasmessi in ViewBag o Model. –

risposta

76

ViewBag è di tipo dynamic ma, è internamente un System.Dynamic.ExpandoObject()

Si dichiara così:

dynamic ViewBag = new System.Dynamic.ExpandoObject();

ed è per questo che si può fare:

ViewBag.Foo = "Bar";

Un codice oggetto Expander di esempio:

public class ExpanderObject : DynamicObject, IDynamicMetaObjectProvider 
{ 
    public Dictionary<string, object> objectDictionary; 

    public ExpanderObject() 
    { 
     objectDictionary = new Dictionary<string, object>(); 
    } 
    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    { 
     object val; 
     if (objectDictionary.TryGetValue(binder.Name, out val)) 
     { 
      result = val; 
      return true; 
     } 
     result = null; 
     return false; 
    } 

    public override bool TrySetMember(SetMemberBinder binder, object value) 
    { 
     try 
     { 
      objectDictionary[binder.Name] = value; 
      return true; 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
    } 
} 
+1

Strano che [dice solo "oggetto pubblico ViewBag {get; } 'sulla pagina MSDN per ViewBag] (https://msdn.microsoft.com/en-us/library/system.web.mvc.controllerbase.viewbag (v = vs.118) .aspx), ma io sono comprando il tuo reclamo che è [un 'ExpandoObject'] (https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject (v = vs.110) .aspx). Mi piace il [confronto con ViewData qui] (http://stackoverflow.com/a/4705446/1028230): "* In pratica [ViewBag] sostituisce le stringhe magiche [in ViewData] ... con proprietà magiche *". ; ^) – ruffin

+0

@ruffin stranamente strano che dice 'oggetto pubblico ViewBag {get; } 'su MSDN, Code dice che è [' ViewBag dinamico {get .. '] (https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponent.cs) che internamente è di tipo [DynamicViewData] (https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/DynamicViewData.cs) –

+0

[Molto bello] (https: // github.com/aspnet/Mvc/blob/8b1bd343ba56152d2a7e677cf041dc9d62b4033f/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponent.cs#L84). Grazie per averlo scoperto. E ho fatto +1 e dico che ti ho creduto! ; ^) – ruffin

5

Il ViewBag è un System.Dynamic.ExpandoObject come suggerito. Le proprietà nello ViewBag sono essenzialmente coppie KeyValue, in cui si accede al valore tramite la chiave. In questo senso, questi sono equivalenti:

ViewBag.Foo = "Bar"; 
ViewBag["Foo"] = "Bar"; 
+0

So che cos'è ViewBag, voglio sapere come creare un oggetto simile in WebForms, il che significa che voglio indicarlo a mano. –

+0

@Aniket Si dispone di un ViewState nei moduli Web. –

32

Si tratta di un oggetto dinamico, significa che è possibile aggiungere proprietà ad esso nel controller, e leggere in un secondo momento nella vista, perché si sono essenzialmente crea l'oggetto come si fa, un caratteristica del tipo dinamico. Vedi questo MSDN article sulla dinamica. Vedi this article sul suo utilizzo in relazione a MVC.

Se si volesse utilizzare questo per moduli web, aggiungere una proprietà dinamica per una classe di pagina di base in questo modo:

public class BasePage : Page 
{ 

    public dynamic ViewBagProperty 
    { 
     get; 
     set; 
    } 
} 

avere tutte le pagine ereditare da questo. Dovresti essere in grado, nel tuo markup ASP.NET, di:

<%= ViewBagProperty.X %> 

Che dovrebbe funzionare. In caso contrario, ci sono modi per aggirarlo.

+0

So che cos'è ViewBag, voglio sapere come creare un oggetto simile in WebForms, il che significa che voglio indicarlo a mano. –

+0

Aggiornato sopra con un'implementazione. –

2

ViewBag è di tipo dinamico. Inoltre, non è possibile fare ViewBag["Foo"]. Otterrete l'eccezione - Impossibile applicare l'indicizzazione con [] a un'espressione di tipo 'System.Dynamic.DynamicObject'.

L'implementazione interna di ViewBag memorizza effettivamente Foo in ViewData["Foo"] (tipo di ViewDataDictionary), quindi quelli 2 sono intercambiabili. ViewData["Foo"] e ViewBag.Foo.

E scope. ViewBag e ViewData servono a trasferire i dati tra le azioni del controllore e a visualizzarli.

4

ViewBag è utilizzato per passare i dati da Azione controller per visualizzare il rendering dei dati che vengono passati. Ora puoi passare i dati utilizzando l'azione Controller e Visualizza usando ViewBag o ViewData. ViewBag: è un tipo di oggetto dinamico, che significa che è possibile aggiungere dinamicamente nuovi campi al viewbag e accedere a questi campi nella vista.È necessario inizializzare l'oggetto di viewbag al momento della creazione di nuovi campi.

ad esempio 1. Creazione di ViewBag: ViewBag.FirstName = "John";

  1. Accesso alla vista: @ ViewBag.FirstName.
-1
public dynamic ViewBag 
{ 
    get 
    { 
     if (_viewBag == null) 
     { 
      _viewBag = new DynamicViewData(() => ViewData); 
     } 

     return _viewBag; 
    } 
} 
+2

Ti chiedo di aggiungere qualche contesto/commento attorno al codice che hai condiviso. Aiuterà il richiedente e gli altri futuri lettori a capire meglio il tuo post. – RBT

0

ViewBag è un tipo dinamico che consentono di impostare in modo dinamico o ottenere valori e consentono di aggiungere un numero illimitato di campi aggiuntivi, senza una classe fortemente tipizzato Essi consentono di passare i dati dal dispositivo di controllo per visualizzare . controller ......

public ActionResult Index() 
{ 
    ViewBag.victor = "My name is Victor"; 
    return View(); 
} 

In considerazione

@foreach(string a in ViewBag.victor) 
{ 
    ......... 
} 

Quello che ho imparato è che entrambi dovrebbero avere la proprietà del nome dinamica salvare cioè ViewBag.victor

Problemi correlati