ASP.NET MVC中的ViewBag如何工作


102

ASP.NET MVC如何ViewBag工作?MSDN说,这只是一个Object让我着迷的,“魔术”属性(例如ViewBag.Foo和魔术弦)ViewBag["Hello"]实际上是如何工作的?

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

实例将不胜感激!


WebForms中似乎不需要此概念,因为页面已经可以直接在文件后面的代码中访问变量。在MVC中,除了在ViewBag或Model中传递的数据外,视图无权访问控制器中的任何内容。
理查德·道尔顿

Answers:


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
奇怪的是,它只是public object ViewBag { get; }在ViewBag的MSDN页面上说了,但我购买您的说法是它是一个ExpandoObject。我喜欢在这里与ViewData进行比较:“ 所以基本上[ViewBag]用魔术属性替换了[ViewData]中的魔术字符串 ”。; ^)
ruffin

@ruffin public object ViewBag { get; }在MSDN上说奇怪的奇怪,代码说它dynamic ViewBag { get .. 内部是DynamicViewData
Aniket Inge

很不错的。感谢您的研究。我+1并说我相信你!; ^)
ruffin

2
@ruffin当文档存在而代码永不存在的另一种情况
Aniket Inge

有时,对于不太清晰/复杂的问题找到正确的答案时,我会印象深刻。谢谢!
奥斯卡·奥尔蒂斯

33

这是一个动态对象,这意味着您可以在控制器中向其添加属性,并稍后在视图中读取它们,因为您实际上是在创建对象时创建动态类型的功能。请参阅有关动态的MSDN文章。请参阅 本文,了解它与MVC的用法。

如果要将其用于Web表单,则将动态属性添加到基类中,如下所示:

public class BasePage : Page
{

    public dynamic ViewBagProperty
    {
        get;
        set;
    }
}

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

<%= ViewBagProperty.X %>

那应该工作。如果没有,则有解决方法。


我知道ViewBag是什么,我想知道如何在WebForms中制作类似的对象,这意味着我想对其进行手工编码。
Aniket Inge 2013年

上面更新了一个实现。
Brian Mains

8

ViewBagSystem.Dynamic.ExpandoObject的建议。中的属性ViewBag本质上是KeyValue对,您可以在其中通过键访问值。从这个意义上讲,它们是等效的:

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

我知道ViewBag是什么,我想知道如何在WebForms中制作类似的对象,这意味着我想对其进行手工编码。
Aniket Inge 2013年

@Aniket您在Web表单中有一个ViewState。
康斯坦丁·迪涅夫

5

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

例如:1.创建ViewBag:ViewBag.FirstName =“ John”;

  1. 访问视图:@ ViewBag.FirstName。

3

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

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

和范围。ViewBag和ViewData可以在Controller的Actions和View呈现的视图之间传递数据。


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.