ViewData和ViewBag有什么区别?


Answers:


388

它使用C#4.0动态功能。它实现了与视图数据相同的目标,应避免使用强类型视图模型(应避免与视图数据相同的方式)。

因此,基本上可以替换魔术字符串

ViewData["Foo"]

具有魔术特性

ViewBag.Foo

为此,您没有编译时的安全性。

我继续怪微软曾经在MVC中引入这个概念。

这些属性的名称区分大小写。


11
您指责Microsoft是出于什么目的?如果没有viewdata,我们如何绑定模型中的dropdownlist。(我认为在模型中使用selectlist并不是一个好主意)
Subin Jacob

15
@SubinJacob如果您想回答这个问题,那么您真的应该提出一个新问题。创建SelectList绝对是制作下拉列表的方法。
MiniRagnarok 2013年

25
我认为这有点主观。强类型的模型很不错,内容十分重要,但对于那些你迅速获得一个视图启动和运行,ViewBag和喜爱做的工作速度比控制器,视图,模型,AutoMapper到视图模型等场景
克雷格·布雷特

11
@Darin,您为什么“怪罪” Microsoft引入了此功能?它只是提供给开发人员的工具。如果您知道自己在做什么,则可以充分利用它。如果您不喜欢它,或者感觉它更容易出错,那就不要使用它。:)
Bilal Fazlani 2015年

5
您如何建议在局部和布局之间传递数据?人们没有看到完整图片时会责备他们。我想您到处都有基本控制器和基本视图模型或静态/单个对象。猜猜是什么,更好地学习使用视图数据,并责怪自己使用了错误的工具来完成工作。
Bart Calixto

42

内部ViewBag属性作为名称/值对存储在ViewData字典中

注意:在MVC 3的大多数预发行版本中,如MVC 3发行说明中的​​以下片段所述,ViewBag属性被命名为ViewModel:

(编辑10-8-12)建议我发布此信息的来源,这里是来源:http : //www.asp.net/whitepapers/mvc3-release-notes#_Toc2_4

MVC 2控制器支持ViewData属性,该属性使您可以使用后绑定字典API将数据传递到视图模板。在MVC 3中,还可以对ViewBag属性使用更简单的语法来实现相同的目的。例如,您可以编写ViewBag.Message =“ text”,而不是编写ViewData [“ Message”] =“ text”。您无需定义任何强类型的类即可使用ViewBag属性。因为它是动态属性,所以您可以只获取或设置属性,它将在运行时动态解析它们。在内部,ViewBag属性作为名称/值对存储在ViewData字典中。(注意:在大多数MVC 3的预发行版本中,ViewBag属性被命名为ViewModel属性。)


这个问题问的是ViewData和之间的区别,而ViewBag不是关于ViewModel
Matthew Flaschen

感谢单挑的马修·弗拉申(Matthew Flaschen),我在响应中输入错误并修复了错误,现在读取“ ViewData”而不是ViewModel,这是一个错误。:)
Rich Bianco

现在不正确。两者均未重命名。它们都仍然存在。一是dynamic支持ViewBag.Message。一种使用旧ViewData["Message"]语法。
马修·弗莱申

1
+1但是,您引用的是什么来源...?应该真正提供一个链接。
山姆

1
谢谢山姆的建议。我已经添加了原始来源的链接。
Rich Bianco 2012年

34

MVC中的ViewBag与ViewData

http://royalarun.blogspot.in/2013/08/viewbag-viewdata-tempdata-and-view.html

ViewBag和ViewData之间的相似之处:

从控制器移至视图时,有助于维护数据。用于将数据从控制器传递到相应的视图。寿命短意味着重定向发生时值变为空。这是因为它们的目标是提供一种在控制器和视图之间进行通信的方法。这是服务器调用中的一种通信机制。

ViewBag和ViewData之间的区别:

ViewData是对象的字典,该对象派生自ViewDataDictionary类,并且可以使用字符串作为键进行访问。ViewBag是一个动态属性,它利用了C#4.0中的新动态功能。ViewData需要对复杂的数据类型进行类型转换,并检查是否为空值以避免错误。ViewBag不需要复杂数据类型的类型转换。

ViewBag和ViewData示例:

public ActionResult Index()
{   
    ViewBag.Name = "Arun Prakash";   
    return View();
}

public ActionResult Index()
{  
    ViewData["Name"] = "Arun Prakash";  
    return View();
}   

在视图中调用

@ViewBag.Name    
@ViewData["Name"]

7
您的答案表明,typecasting但您没有显示类型转换的执行方式
Alex

31

ViewData注意:它要求对复杂数据类型进行类型转换,并检查空值以避免错误。

ViewBag:对于复杂的数据类型,不需要类型转换。

考虑以下示例:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var emp = new Employee
        {
            EmpID=101,
            Name = "Deepak",
            Salary = 35000,
            Address = "Delhi"
        };

        ViewData["emp"] = emp;
        ViewBag.Employee = emp;

        return View(); 
    }
}

的代码View如下:

@model MyProject.Models.EmpModel;
@{ 
 Layout = "~/Views/Shared/_Layout.cshtml"; 
 ViewBag.Title = "Welcome to Home Page";
 var viewDataEmployee = ViewData["emp"] as Employee; //need type casting
}

<h2>Welcome to Home Page</h2>
This Year Best Employee is!
<h4>@ViewBag.Employee.Name</h4>
<h3>@viewDataEmployee.Name</h3>

6
帮助我理解,但我认为这是一个错误。这 <h4>@ViewBag.emp.Name</h4> 应该更改为<h4>@ViewBag.Employee.Name</h4>
Benny Margalit

24

所有的答案表明,ViewBag和/或ViewData为传递数据从ControllerViews这是误传。两者都非常有用,可以将数据从视图传递到布局或将部分视图传递到视图(或ViewComponents等)。这不是控制器专有的。

作为默认的asp.net示例在布局页面中具有以下内容:

<title>@ViewData["Title"] - MyApp</title>

并且在任何视图中

ViewData["Title"] = "Details";

那么,问一个问题:“ ViewBag和之间有什么区别ViewData?”

最显着的区别是ViewData强类型字典,而 ViewBag动态类型。

注意里面的数据是一样的

ViewData["Title"] = "MyTitle";
ViewBag.Title; // returns "MyTitle";

什么时候使用一个或另一个?

  • ViewBag不支持无效的C#名称。您无法ViewData["Key With Space"]使用ViewBag
  • ViewBag.Something 是动态的,在调用需要在编译时知道确切参数的方法(例如扩展方法)时,您可能会遇到问题。
  • ViewBag 可以检查语法语法是否为空: ViewBag.Person?.Name
  • ViewData具有Dictionary的所有属性,如ContainsKeyAdd等,因此请ViewData.Add("somekey", "somevalue")记住它可能会引发异常。
  • ViewData在视图上使用时需要TypeCasting,而在ViewBag不需要时。

知道细微的差异,使用一种或另一种则更喜欢口味。

通常您可以想到ViewBag.AnyKey一个别名ViewData["AnyKey"]


1
这应该是一个可以接受的答案!
Prashant Pimpale

14

我可以建议您不要使用吗?

如果要将数据“发送”到屏幕,请发送强类型对象(AKA ViewModel),因为它更易于测试。

如果您绑定到某种“模型”并具有随机的“ viewbag”或“ viewdata”项,则将使自动测试变得非常困难。

如果使用这些,请考虑如何重组并仅使用ViewModels。


4
忽略“编译器是第一个单元测试”的原则,静态类型的视图模型如何使您的代码比动态类型的代码更具可测试性?尽管在动态类型的解决方案中对测试的要求更为重要,但是如果两个解决方案都实现相同数量和类型的测试,那么您将一无所获。
达伦·刘易斯

我同意,这有点模糊。也许涉及智能感知。
约书亚·拉米雷斯

1
一个例子就是嘲弄。如果要对控制器动作进行单元测试,则创建一个“模拟”对象以进行传递和断言要比尝试断言某些字符串已添加到某些字典或某些动态字段设置为某个值要容易得多,它是与具有一个“请求”和一个“响应”对象而不是采用多个参数的服务合同类似的概念。
13年

如果不使用两者,如何将数据从视图传递到布局?-1
Bart Calixto

这个答案如何?
JSON


6

viewdata:是用于在View和Controller之间存储数据的字典,您需要将视图数据对象强制转换为视图中的相应模型,以便能够从中检索数据...

ViewBag:是一种动态属性,其工作方式类似于视图数据,但是更好的原因是,在视图中使用它之前,不需要将其强制转换为对应的模型...


4

以下是关于ViewData,ViewBag,TempData和Session的点对点差异。 信用/复制的askforprogram.in,请单击链接以获取此处未提及的代码示例。

  1. MVC中的ViewData

    • ViewData是ControllerBase类的属性。
    • ViewData是字典对象的一种。
    • ViewData是键值字典集合。
    • ViewData是在MVC 1.0版本中引入的。
    • ViewData可与.Net Framework 3.5及更高版本一起使用。
    • 枚举时需要进行代码的类型转换。
    • ViewData对象仅保留当前请求的数据。
  2. MVC中的ViewBag

    • ViewBag是ControllerBase类的属性。
    • ViewBag是一种动态对象。
    • ViewBag是一种对象。
    • ViewBag是在MVC 3.0版本中引入的。
    • ViewBag可与.Net Framework 4.0及更高版本一起使用。
    • ViewBag使用属性并对其进行处理,因此在枚举时无需进行类型转换。
    • ViewBag对象仅保留当前请求的数据。
  3. MVC中的TempData

    • TempData是ControllerBase类的属性。
    • TempData是字典对象的一种。
    • TempData是键值字典集合。
    • 在MVC 1.0版本中引入了TempData。
    • TempData可与.Net Framework 3.5及更高版本一起使用。
    • 枚举时需要进行代码的类型转换。
    • TempData对象用于在当前请求和后续请求之间进行数据处理。
  4. 在MVC中的会话

    • 会话是Controller(Abstract Class)的属性。
    • 会话是HttpSessionStateBase的一种。
    • 会话是键值字典集合。
    • 会话是在MVC 1.0版本中引入的。
    • TempData可与.Net Framework 1.0及更高版本一起使用。
    • 枚举时需要进行代码的类型转换。
    • 会话对象保留所有请求的数据。对所有请求均有效,永不过期。

1

尽管选择一种格式相对于另一种格式可能没有技术优势,但是您应该意识到两种语法之间的一些重要区别。一个明显的区别是ViewBag仅在您访问的密钥是有效的C#标识符时才起作用。例如,如果您在ViewData [“ Key With Spaces”]中放置一个值,则由于无法编译代码,因此无法使用ViewBag访问该值。要考虑的另一个关键问题是,您不能将动态值作为参数传递给扩展方法。为了选择正确的扩展方法,C#编译器必须在编译时知道每个参数的真实类型。如果任何参数是动态的,编译将失败。例如,此代码将始终失败:@ Html.TextBox(“ name”,ViewBag.Name)。要解决此问题,请使用ViewData [“ Name”


0
public ActionResult Index()
{
    ViewBag.Name = "Monjurul Habib";
    return View();
}

public ActionResult Index()
{
    ViewData["Name"] = "Monjurul Habib";
    return View();
} 

In View:

@ViewBag.Name 
@ViewData["Name"] 

0

这样,我们可以使其使用值在控制器之间使用TEMP DATA将信息传递到其他页面


0

我注意到ViewData和ViewBag之间的主要区别是:

ViewData:它将返回的对象与您分配给它的对象无关,并且需要再次类型转换为原始类型。

ViewBag:返回指定的确切类型是足够聪明的,无论您分配的是简单类型(即int,字符串等)还是复杂类型都无所谓。

例如:控制器代码。

 namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Products p1 = new Products();
            p1.productId = 101;
            p1.productName = "Phone";
            Products p2 = new Products();
            p2.productId = 102;
            p2.productName = "laptop";

            List<Products> products = new List<Products>();
            products.Add(p1);
            products.Add(p2);
            ViewBag.Countries = products;
            return View();
        }
    }
    public class Products
    {
        public int productId { get; set; }
        public string productName { get; set; }
    }
}

查看代码。

<ul>
            @foreach (WebApplication1.Controllers.Products item in ViewBag.Countries)
            {
            <li>@item.productId &nbsp;&nbsp;&nbsp;@item.productName</li>
            }
        </ul>

输出屏幕。

在此处输入图片说明


0

查看资料

  1. ViewData用于将数据从控制器传递到视图
  2. ViewData派生自ViewDataDictionary类,基本上是一个Dictionary对象,即Keys和Values,其中Keys是String,而Values是对象。
  3. 从ViewData检索数据时需要进行数据拼写,这是因为其对象类型为数据,并且在类型转换之前也要进行空vvalue检查,否则它将破坏应用程序。如果发生重定向,则其值将为null读取TempData ViewData和View Bag之间的完整差异

http://www.gurujipoint.com/2017/09/view-data-viewbag-and-tempdata.html


0
ViewData
  1. ViewData用于将数据从控制器传递到视图
  2. 它是从ViewDataDictionary类派生的
  3. 它仅适用于当前请求
  4. 需要复杂数据类型的类型转换,并检查空值以避免错误
  5. 如果发生重定向,则其值将为null
ViewBag
  1. ViewBag还用于将数据从控制器传递到相应的视图
  2. ViewBag是一个动态属性,它利用了C#4.0中的新动态功能
  3. 它也仅适用于当前请求
  4. 如果发生重定向,则其值将为null
  5. 不需要复杂数据类型的类型转换

0

这里,ViewDataViewBag都用于将数据从Controller传递到View

1. ViewData

-ViewData是从ViewDataDictonary类派生的字典对象。

-数据仅允许一个请求,发生页面重定向时,ViewData值将被清除。

-ViewData值必须在使用前键入cate。

示例: 在控制器中

public ActionResult PassingDatatoViewWithViewData()
{
      ViewData["Message"] = "This message shown in view with the ViewData";
      return View();
}

视野中

@ViewData["Message"];

-如果使用ViewData是像KeyValue这样的对,则Message是Key,而用逗号分隔的值是Value。

-数据很简单,所以如果数据很复杂,那么我们就不能在这里使用类型转换,而要使用类型转换。

public ActionResult PassingDatatoViewWithViewData()
{
      var type= new List<string>
    {
        "MVC",
        "MVP",
        "MVVC"
    };
    ViewData["types"] = type;
    return View();
}

-在View中数据可以提取为

<ul>
        @foreach (var items in (List<string>)ViewData["types"])
        {
         <li>@items</li>
        }
  </ul>

2. ViewBag

--ViewBag使用动态功能。围绕ViewData的ViewBag包装器。

-在ViewBag中需要强制类型转换。

-与ViewData相同,如果发生重定向,则值将为null。

例:

public ActionResult PassingDatatoViewWithViewBag()
{
          ViewData.Message = "This message shown in view with the ViewBag";
          return View();
}

视野中

@ViewBag.vbMessage

-对于复杂类型,请使用ViewBag

public ActionResult PassingDatatoViewWithViewBag()
{
          var type= new List<string>
        {
            "MVC",
            "MVP",
            "MVVC"
        };
        ViewBag.types = type;
        return View();
 }

-在View中数据可以提取为

<ul>
       @foreach (var items in ViewBag.types)
       {
         <li>@items</li>
       }
</ul>

-主要区别在于ViewBag不需要强制转换,而ViewData是必需强制转换。


-1

ViewBag和ViewData是用于在ASP.Net MVC中将信息从控制器传递到视图的两种方法。使用这两种机制的目的是提供控制器和View之间的通信。两者都有很短的寿命,一旦发生重定向,即一旦页面从源页面(我们在其中设置了ViewBag或ViewData的值)重定向到目标页面,ViewBag和ViewData的值都变为null。变为空。

尽管有这些相似之处,但如果我们谈论两者的实现,两者(ViewBag和ViewData)是两个不同的东西。区别如下:

1.)如果我们仔细分析这两种实现方式,则会发现ViewData是一个字典数据结构-对象字典,它是从ViewDataDictionary派生的,并且可以使用字符串作为这些值的键进行访问,而ViewBag则利用了C#4.0和是动态属性。

2.)在从ViewData访问值时,我们需要对值(数据类型)进行类型转换,因为它们作为对象存储在ViewData字典中,但是如果在使用ViewBag的情况下访问值,则不需要这样。

3.)在ViewBag中,我们可以像这样设置值:

      ViewBag.Name = "Value"; 

并可以如下访问:

          @ViewBag.Name

对于ViewData,可以按以下方式设置和访问值:如下设置ViewData:

ViewData["Name"] = "Value";

并像这样获得价值

 @ViewData["Name"] 

有关更多详细信息,请单击此处:


2
抱歉,我对此表示不满,但是这个答案用了几段时间说没什么用。我从rachelappel.com/
Chris F Carroll
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.