2013-02-15 142 views
87

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

另外,我怎样才能使一个在我的ASP.NET应用程序的WebForms使用它?

示例将非常感谢!

+0

概念没有按”在WebForms中似乎是需要的,因为页面已经可以直接访问文件后面的代码中的变量。而在MVC中,视图除了在ViewBag或Model中传递的数据外,不能访问控制器中的任何内容。 – 2013-02-15 14:01:10

回答

76

ViewBagdynamic类型,但是,在内部的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

奇怪的是[它只是说'公共对象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 2016-02-25 21:28:45

+0

@ruffin奇怪的是,它说'公共对象ViewBag {get; }'MSDN上,典说,这是['动态ViewBag {得到..'(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) – 2016-02-26 09:44:09

+0

[非常好的](HTTPS的:// github.com/aspnet/Mvc/blob/8b1bd343ba56152d2a7e677cf041dc9d62b4033f/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponent.cs#L84)。感谢您的挖掘。我做了+1并说我相信你! ; ^) – ruffin 2016-02-26 15:05:55

5

ViewBagSystem.Dynamic.ExpandoObject的建议。 ViewBag中的属性本质上是KeyValue对,您可以在其中通过键访问值。在这个意义上,这些是相同的:

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

我知道ViewBag是什么,我想知道如何在WebForms中制作这样的对象,这意味着我想手工编写它。 – 2013-02-15 13:47:02

+0

@Aniket您在Web表单中有一个ViewState。 – 2013-02-15 14:05:15

32

这是一个动态的对象,这意味着你可以在控制器属性添加到它,并在视图以后读的,因为你基本上是创建该对象为你做什么,一个动态类型的特征。有关动力学,请参阅此MSDN article。有关与MVC相关的用法,请参阅this article

如果你想用这个Web表单,动态属性添加到基本页类,像这样:

public class BasePage : Page 
{ 

    public dynamic ViewBagProperty 
    { 
     get; 
     set; 
    } 
} 

有您的所有网页从这个继承。您应该能够在您的ASP.NET标记中执行以下操作:

<%= ViewBagProperty.X %> 

这应该起作用。如果没有,有办法解决它。

+0

我知道ViewBag是什么,我想知道如何在WebForms中制作这样的对象,这意味着我想手工编写它。 – 2013-02-15 13:47:31

+0

上面更新了一个实现。 – 2013-02-15 13:59:13

2

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

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

和范围。 ViewBag和ViewData可以在控制器的动作和查看渲染之间传递数据。

4

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

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

  1. 访问视图: @ ViewBag.FirstName。
-1
public dynamic ViewBag 
{ 
    get 
    { 
     if (_viewBag == null) 
     { 
      _viewBag = new DynamicViewData(() => ViewData); 
     } 

     return _viewBag; 
    } 
} 
+2

我请你,请添加你身边有共同的代码中的一些背景/评论的另一种情况。这将有助于提问者和其他未来的读者更好地理解你的帖子。 – RBT 2016-12-28 08:42:42

0

ViewBag是一个动态的类型,使您可以动态地设置或获取值,并允许您添加任意数量的附加字段没有一个强类型的类 它们允许你从控制器传递数据,查看。 在控制器......

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

鉴于

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

我学到的是,两者都应该有保存动态name属性即ViewBag.victor