我在MVC 3中看到了ViewBag。这和MVC 2中的ViewData有什么不同?


当前回答

ViewData

ViewData用于将数据从控制器传递给ViewData,它是从viewdatdictionary类派生出来的。仅对当前请求可用。仅要求复杂数据类型的类型转换,并检查null值以避免错误。如果发生重定向,则其值为null

ViewBag

ViewBag是一个动态属性,它利用了c# 4.0中的新动态特性。它也仅对当前请求可用。如果发生重定向,则其值为null

其他回答

ViewData

ViewData用于将数据从控制器传递给ViewData,它是从viewdatdictionary类派生出来的。仅对当前请求可用。仅要求复杂数据类型的类型转换,并检查null值以避免错误。如果发生重定向,则其值为null

ViewBag

ViewBag是一个动态属性,它利用了c# 4.0中的新动态特性。它也仅对当前请求可用。如果发生重定向,则其值为null

这里ViewData和ViewBag都用于将数据从控制器传递到视图。

1. 显示数据

——ViewData是字典对象,从ViewDataDictonary类派生。

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

——ViewData值必须在使用前输入。

示例:在控制器中

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

在视图

@ViewData["Message"];

——ViewData是Key和Value这样的一对,Message是Key,在倒逗号中Value是Value。

数据是简单的,所以我们不能在这里使用类型转换,如果数据是复杂的,那么使用类型转换。

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

在视图中数据可以提取为

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

2. ViewBag

——ViewBag使用动态特性。ViewBag包装了ViewData。

—在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();
 }

在视图中数据可以提取为

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

主要的区别是ViewBag不需要类型转换,而ViewData需要类型转换。

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>

我能建议你不要用吗?

如果你想“发送”数据到你的屏幕上,发送一个强类型对象(又名ViewModel),因为它更容易测试。

如果你绑定到某种类型的“模型”,并拥有随机的“viewbag”或“viewdata”项,那么这会使自动化测试变得非常困难。

如果您正在使用这些,请考虑如何重构并仅使用ViewModels。

在ViewBag内部,属性以名称/值对的形式存储在ViewData字典中。

注意:在MVC 3的大多数预发布版本中,ViewBag属性被命名为ViewModel,这段代码来自MVC 3发布说明:

有人建议我发布我发布的这个信息的来源,下面是来源: http://www.asp.net/whitepapers/mvc3-release-notes#_Toc2_4

MVC 2 controllers support a ViewData property that enables you to pass data to a view template using a late-bound dictionary API. In MVC 3, you can also use somewhat simpler syntax with the ViewBag property to accomplish the same purpose. For example, instead of writing ViewData["Message"]="text", you can write ViewBag.Message="text". You do not need to define any strongly-typed classes to use the ViewBag property. Because it is a dynamic property, you can instead just get or set properties and it will resolve them dynamically at run time. Internally, ViewBag properties are stored as name/value pairs in the ViewData dictionary. (Note: in most pre-release versions of MVC 3, the ViewBag property was named the ViewModel property.)