103

ASP.NET MVC 是如何ViewBag工作的?MSDN 说它只是一个Object,这让我很感兴趣,“魔术”属性如ViewBag.Foo和 魔术字符串ViewBag["Hello"]实际上是如何工作的?

另外,如何制作一个并在我的 ASP.NET WebForms 应用程序中使用它?

例子将不胜感激!

4

7 回答 7

92

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;
        }
    }
}
于 2013-02-20T17:15:53.487 回答
33

它是一个动态对象,这意味着您可以在控制器中为其添加属性,然后在视图中读取它们,因为您本质上是在创建对象,这是动态类型的一个特征。请参阅这篇关于动态的MSDN 文章。请参阅 这篇文章,了解它与 MVC 相关的用法。

如果您想将此用于 Web 表单,请向基页类添加动态属性,如下所示:

public class BasePage : Page
{

    public dynamic ViewBagProperty
    {
        get;
        set;
    }
}

让您的所有页面都继承自此。您应该能够在 ASP.NET 标记中执行以下操作:

<%= ViewBagProperty.X %>

那应该行得通。如果没有,有办法解决它。

于 2013-02-15T13:43:48.067 回答
8

ViewBag正如System.Dynamic.ExpandoObject建议的那样。中的属性ViewBag本质上是KeyValue对,您可以通过键访问值。在这个意义上,这些是等价的:

ViewBag.Foo = "Bar";
ViewBag["Foo"] = "Bar";
于 2013-02-15T13:42:45.467 回答
5

ViewBag 用于将数据从 Controller Action 传递到 view 以呈现正在传递的数据。现在您可以使用 ViewBag 或 ViewData 在 Controller Action 和 View 之间传递数据。ViewBag:它是动态对象的类型,这意味着您可以动态地将新字段添加到 viewbag 并在 View 中访问这些字段。您需要在创建新字段时初始化 viewbag 的对象。

eg: 1. 创建 ViewBag: ViewBag.FirstName="John";

  1. 访问视图:@ViewBag.FirstName。
于 2015-11-20T04:30:50.253 回答
3

ViewBag 属于动态类型。更多,你做不到ViewBag["Foo"]。您将得到异常 -无法使用 [] 将索引应用于 'System.Dynamic.DynamicObject' 类型的表达式

ViewBag实际上将 Foo 存储到ViewData["Foo"](ViewDataDictionary 的类型)的内部实现,所以这两个是可以互换的。ViewData["Foo"]ViewBag.Foo

和范围。ViewBag 和 ViewData 用于在 Controller 的 Actions 和它呈现的 View 之间传递数据。

于 2013-02-15T13:52:42.097 回答
1

ViewBag 是一种动态类型,允许您动态设置或获取值,并允许您添加任意数量的附加字段而无需强类型类它们允许您将数据从控制器传递到视图。在控制器中......

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

在视图中

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

我了解到的是,两者都应该具有保存动态名称属性,即 ViewBag.victor

于 2018-01-18T10:56:28.290 回答
-1
public dynamic ViewBag
{
    get
    {
        if (_viewBag == null)
        {
            _viewBag = new DynamicViewData(() => ViewData);
        }

        return _viewBag;
    }
}
于 2016-12-28T06:11:35.257 回答