Как работает ViewBag в ASP.NET MVC


102

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

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

Были бы очень признательны за примеры!


Эта концепция, похоже, не нужна в WebForms, поскольку страница уже имеет прямой доступ к переменным в ее коде за файлом. В то время как в MVC представление не имеет доступа ни к чему в контроллере, кроме данных, которые передаются в представлении ViewBag или Model.
Ричард Далтон,

Ответы:


91

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
Weird , что он просто говорит , что public object ViewBag { get; }на странице MSDN для ViewBag , но я покупаю ваши претензии , что это . Мне нравится сравнение с ViewData здесь : « Итак, в основном [ViewBag] заменяет магические строки [в ViewData] ... магическими свойствами ». ; ^)ExpandoObject
ruffin

@ruffin: как ни странно, странно, что public object ViewBag { get; }в MSDN написано, dynamic ViewBag { get .. что код говорит, что он внутренне относится к типу DynamicViewData
Аникет Инге,

Очень хорошо . Спасибо, что откопали это. И я сделал +1 и сказал, что верил тебе! ; ^)
ruffin

2
@ruffin еще один случай, когда документация лжет, а код никогда не лжет
Аникет Инге

Иногда меня впечатляет, когда я нахожу правильные ответы на не очень четкие / смешанные вопросы. Спасибо!
Оскар Ортис

33

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

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

public class BasePage : Page
{

    public dynamic ViewBagProperty
    {
        get;
        set;
    }
}

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

<%= ViewBagProperty.X %>

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


Я знаю, что такое ViewBag, я хочу знать, как создать такой объект в WebForms, а это значит, что я хочу написать его вручную.
Аникет Инге

Обновлено выше с реализацией.
Брайан Мэйнс,

8

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

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

Я знаю, что такое ViewBag, я хочу знать, как создать такой объект в WebForms, а это значит, что я хочу написать его вручную.
Аникет Инге

@Aniket У вас есть ViewState в веб-формах.
Константин Динев

5

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

например: 1. Создание ViewBag: ViewBag.FirstName = "John";

  1. Доступ к представлению: @ ViewBag.FirstName.

3

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

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

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


0

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

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

Ввиду

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

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


-1
public dynamic ViewBag
{
    get
    {
        if (_viewBag == null)
        {
            _viewBag = new DynamicViewData(() => ViewData);
        }

        return _viewBag;
    }
}

3
Прошу вас добавить контекст / комментарий к коду, которым вы поделились. Это поможет тому, кто задает вопрос, и другим будущим читателям лучше понять ваш пост.
RBT
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.