2013-02-15 3 views
87

Как работает ASP.NET MVC ViewBag? MSDN говорит, что это всего лишь Object, что меня интригует, как на самом деле работают «магические» свойства, такие как ViewBag.Foo и магические строки ViewBag["Hello"]?Как работает ViewBag в ASP.NET MVC

Также, как я могу его использовать и использовать в своем приложении ASP.NET WebForms?

Примеры были бы очень оценены!

+0

Концепция Безразлично» t, похоже, требуется в WebForms, поскольку страница уже имеет прямой доступ к переменным в коде за файлом. В то время как в MVC представление не имеет доступа к чему-либо в контроллере, кроме данных, которые передаются с ViewBag или Model. –

ответ

76

ViewBag имеет тип dynamic, но внутренне System.Dynamic.ExpandoObject()

Заявлено, как это:

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

поэтому вы можете сделать:

ViewBag.Foo = "Bar";

Код объекта расширителя образца:

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

Странно, что [это просто говорит 'public object ViewBag {get; } 'на странице MSDN для ViewBag] (https://msdn.microsoft.com/en-us/library/system.web.mvc.controllerbase.viewbag (v = vs.118) .aspx), но я покупая ваше утверждение о том, что это [ExpandoObject'] (https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject (v = vs.110) .aspx). Мне нравится [сравнение с ViewData здесь] (http://stackoverflow.com/a/4705446/1028230): «* В основном [ViewBag] заменяет магические строки [в ViewData] ... с волшебными свойствами *". ; ^) – ruffin

+0

@ruffin странно странно, что он говорит 'public object ViewBag {get; } 'в MSDN, Code говорит, что это [' dynamic ViewBag {get .. '] (https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponent.cs), который внутренне имеет тип [DynamicViewData] (https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/DynamicViewData.cs) –

+0

[Очень приятно] (https: // github.com/aspnet/Mvc/blob/8b1bd343ba56152d2a7e677cf041dc9d62b4033f/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponent.cs#L84). Спасибо, что выкопали это. И я сделал +1 и сказал, что я тебе поверил! ; ^) – ruffin

5

ViewBag - System.Dynamic.ExpandoObject как предложено. Свойствами в ViewBag являются, по существу, KeyValue пары, где вы получаете доступ к значению с помощью ключа. В этом смысле они эквивалентны:

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

Я знаю, что такое ViewBag, я хочу знать, как сделать такой объект в WebForms, что означает, что я хочу его вручную обработать. –

+0

@Aniket У вас есть ViewState в веб-формах. –

32

Это динамический объект, то есть вы можете добавить свойства к нему в контроллере, и прочитать их позже в представлении, потому что вы, по сути создавая объект, как вы делаете, особенность динамического типа. См. Это MSDN article о динамике. См. this article о его использовании по отношению к MVC.

Если вы хотите использовать это для веб-форм, добавить динамическое свойство к классу базовой страницы, как так:

public class BasePage : Page 
{ 

    public dynamic ViewBagProperty 
    { 
     get; 
     set; 
    } 
} 

Есть все страницы наследуют от этого. Вы должны уметь в своей разметке ASP.NET:

<%= ViewBagProperty.X %> 

Это должно сработать. Если нет, есть способы обойти это.

+0

Я знаю, что такое ViewBag, я хочу знать, как сделать такой объект в WebForms, что означает, что я хочу его вручную обработать. –

+0

Обновлено выше с реализацией. –

2

ViewBag имеет динамический тип. Больше, вы не можете сделать ViewBag["Foo"]. Вы получите исключение - Невозможно применить индексирование с [] к выражению типа «System.Dynamic.DynamicObject».

Внутренняя реализация ViewBag фактически хранит Foo в ViewData["Foo"] (тип ViewDataDictionary), поэтому эти 2 являются взаимозаменяемыми. ViewData["Foo"] и ViewBag.Foo.

И области. ViewBag и ViewData предназначены для передачи данных между действиями Controller и View it Renders.

4

ViewBag используется для передачи данных из действия контроллера для просмотра передаваемых данных. Теперь вы можете передавать данные, используя действия Controller Action и View, либо с помощью ViewBag, либо ViewData. ViewBag: это тип динамического объекта, что означает, что вы можете добавлять новые поля для динамического просмотра и получать доступ к этим полям в представлении.Вам нужно инициализировать объект viewbag во время создания новых полей.

e.g: 1. Создание ViewBag: ViewBag.FirstName = "John";

  1. Доступ для просмотра: @ ViewBag.FirstName.
-1
public dynamic ViewBag 
{ 
    get 
    { 
     if (_viewBag == null) 
     { 
      _viewBag = new DynamicViewData(() => ViewData); 
     } 

     return _viewBag; 
    } 
} 
+2

Прошу вас, пожалуйста, добавить некоторый контекст/комментарий вокруг кода, которым вы поделились. Это поможет акиру и другим будущим читателям лучше понять ваше сообщение. – RBT

0

ViewBag представляет собой динамический тип, который позволяет динамически устанавливать или получать значения и позволяет добавлять любое количество дополнительных полей без строго типизированного класса Они позволяют передавать данные от контроллера для просмотра , В контроллере ......

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

Ввиду

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

То, что я узнал, что оба должны иметь сохранить динамическое имя свойства т.е. ViewBag.victor

Смежные вопросы