ChatGPT解决这个技术问题 Extra ChatGPT

ViewData 和 ViewBag 有什么区别?

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


A
Adaptabi

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

所以基本上它取代了魔术字符串:

ViewData["Foo"]

具有魔法属性:

ViewBag.Foo

您没有编译时安全性。

我继续指责微软在 MVC 中引入了这个概念。

属性名称区分大小写。


你指责微软的目的是什么?如果没有视图数据,我们如何从模型中绑定下拉列表。 (我认为在模型中使用 selectlist 不是一个好主意)
@SubinJacob 如果你想要这个问题的答案,你真的应该提出一个新问题。创建一个 SelectList 绝对是制作下拉列表的方法。
我认为这有点主观。强类型模型很好,而且 yada yada,但是对于快速启动和运行视图的场景,ViewBag 等比 Controller、View、Model、AutoMapper 到 ViewModel 等更快地完成这项工作。
@Darin,你为什么要“责怪”微软介绍这个?它只是提供给开发人员的工具。如果你知道你在做什么,你就可以充分利用它。如果您不喜欢它或觉得它更容易出错,请不要使用它。 :)
你建议如何在部分和布局之间传递数据?人们在看不到全貌时会责备。我想你到处都有基本控制器和基本视图模型或静态/单例对象。你猜怎么着,最好学会使用视图数据,并责备自己使用错误的工具来完成这项工作。
R
Rich Bianco

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

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

(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 属性。)


该问题询问的是 ViewDataViewBag 之间的区别,而不是关于 ViewModel
感谢 Matthew Flaschen 的提醒,我在回复中有错字并修复了它,现在读取“ViewData”而不是 ViewModel,这是一个错误。 :)
现在是不正确的。两者都没有重命名为另一个。它们都仍然存在。一个是 dynamic 并支持 ViewBag.Message。一种使用旧的 ViewData["Message"] 语法。
+1但是,您引用的是什么来源...?真的应该提供一个链接。
谢谢山姆的建议。我添加了指向原始来源的链接。
m
mmking

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"]

您的回答表明typecasting,但您没有显示如何执行类型转换
D
Doga Fincan

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>

帮助我理解,但我认为有一个错误。此 <h4>@ViewBag.emp.Name</h4> 应更改为 <h4>@ViewBag.Employee.Name</h4>
B
Bart Calixto

所有答案都表明 ViewBag 和/或 ViewData 是将数据从 Controller 传递到 Views,这是错误信息。两者对于将数据从 Views 传递到 Layout 或 Partial 到 Views(或 ViewComponents 等)都非常有用。它不是控制器独有的。

作为默认的 asp.net 示例,在布局页面中有这个:

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

在任何情况下

ViewData["Title"] = "Details";

那么,要问这个问题:“ViewBagViewData 有什么区别?”

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

注意里面的数据是一样的

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

何时使用一种或另一种?

ViewBag 不支持无效的 C# 名称。您无法使用 ViewBag 访问 ViewData["Key With Space"]

ViewBag.Something 是动态的,在调用需要在编译时知道确切参数的方法(如扩展方法)时可能会遇到问题。

ViewBag 可以检查空值语法清理器:ViewBag.Person?.Name

ViewData 具有 Dictionary 的所有属性,例如 ContainsKey、Add 等,因此您可以使用 ViewData.Add("somekey", "somevalue") 记住它可能会引发异常。

在视图上使用 ViewData 需要 TypeCasting 而 ViewBag 不需要。

了解细微的差异,使用一种或另一种更多的是一种口味偏好。

通常你可以把 ViewBag.AnyKey 想成 ViewData["AnyKey"] 的别名


这实际上是最完整的答案。
n
nootn

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

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

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

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


忽略“编译器是第一个单元测试”原则,静态类型的视图模型如何使您的代码比动态类型更易于测试?虽然在动态类型的解决方案中对测试的要求更为重要,但如果两种解决方案都实现了相同数量和类型的测试,那么您不会失去任何东西。
我同意,这有点模糊。也许涉及智能感知。
一个例子是嘲笑。如果您想对控制器操作进行单元测试,创建一个“模拟”对象来传递和断言比尝试断言某些字符串已添加到某个字典或某些动态字段设置为某个值更容易 - 它是与具有一个“请求”和一个“响应”对象的服务合同类似的概念,而不是采用多个参数。
如果不使用任何一种,您将如何将数据从视图传递到布局? -1
这是一个怎样的答案?
A
Alan Macdonald

有一些细微的差异意味着您可以以与视图略有不同的方式使用 ViewData 和 ViewBag。这篇文章 http://weblogs.asp.net/hajan/archive/2010/12/11/viewbag-dynamic-in-asp-net-mvc-3-rc-2.aspx 中概述了一个优点,并表明在示例中可以通过使用 ViewBag 而不是 ViewData 来避免强制转换。


A
Ahmed Elbatt

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

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


N
Nirju

下面是关于 ViewData、ViewBag、TempData 和 TempData 的点对点区别。会议。 Credit/copied askforprogram.in,点击此处未提及的代码示例的链接。

MVC ViewData 中的 ViewData 是 ControllerBase 类的属性。 ViewData 是一种字典对象。 ViewData 是键值字典集合。 ViewData 是在 MVC 1.0 版本中引入的。 ViewData 适用于 .Net 框架 3.5 及更高版本。枚举时需要对代码进行类型转换。 ViewData 对象仅保留当前请求的数据。 MVC ViewBag 中的 ViewBag 是 ControllerBase 类的属性。 ViewBag 是一种动态对象。 ViewBag 是一种对象。 ViewBag 是在 MVC 3.0 版本中引入的。 ViewBag 适用于 .Net 框架 4.0 及更高版本。 ViewBag 使用属性并对其进行处理,因此在枚举时无需进行类型转换。 ViewBag 对象仅保留当前请求的数据。 MVC TempData 中的 TempData 是 ControllerBase 类的属性。 TempData 是一种字典对象。 TempData 是键值字典集合。 TempData 是在 MVC 1.0 版本中引入的。 TempData 适用于 .Net 框架 3.5 及更高版本。枚举时需要对代码进行类型转换。 TempData 对象用于当前请求和后续请求之间的数据。 MVC Session 中的 Session 是 Controller(抽象类)的属性。 Session 是 HttpSessionStateBase 的一种。会话是键值字典集合。 Session 是在 MVC 1.0 版本中引入的。 TempData 适用于 .Net 框架 1.0 及更高版本。枚举时需要对代码进行类型转换。会话对象保存所有请求的数据。适用于所有请求,永不过期。


u
user2211290

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


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

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

In View:

@ViewBag.Name 
@ViewData["Name"] 

u
user3141962

通过这种方式,我们可以使它使用这些值将控制器之间的信息传递到带有 TEMP DATA 的其他页面


L
Liam

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

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

ViewBag :返回您分配给它的确切类型已经足够聪明了,无论您分配简单类型(即 int、string 等)还是复杂类型都无关紧要。

例如:控制器代码。

 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>

输出屏幕。

https://i.stack.imgur.com/wtDM7.png


E
Er Pravin Suthar

ViewData 用于将数据从控制器传递到视图 它派生自 ViewDataDictionary 类 仅适用于当前请求 需要对复杂数据类型进行类型转换并检查空值以避免错误 如果发生重定向,则其值变为空

ViewBag 还用于将数据从控制器传递到相应的视图 ViewBag 是一个动态属性,它利用了 C# 4.0 中的新动态特性 它也仅适用于当前请求 如果发生重定向,则其值变为 null 不' t 需要对复杂数据类型进行类型转换


B
Brijesh Mavani

这里 ViewData 和 ViewBag 都用于将数据从 Controller 传递到 View。

1.查看数据

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

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

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

示例:在控制器中

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

-- In View 数据可以提取为

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

2.ViewBag

--ViewBag 在 ViewData 周围使用动态 feature.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();
 }

-- In View 数据可以提取为

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

-- 主要区别在于 ViewBag 不需要类型转换,但 ViewData 需要类型转换。


P
Peter Csala

查看包

它返回类型对象。它是 ControllerBase 类的动态属性。 ViewBag 仅适用于 .NET Framework 4.0 及更高版本。由于 ViewBag 属性本质上是动态的,因此在使用前不需要 TypeCasting。 ViewBag 返回动态类型对象,它的属性也是动态的。它比 ViewData 快一点。

查看数据

它返回键值字典对集合。 ViewData 是一个字典对象,它是 ControllerBase 类的属性。 ViewData 比 ViewBag 快。枚举时需要类型转换代码,因为它是字典对集合。 ViewData返回对象(键值对的类型,值是对象类型,使用前需要强制转换)

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

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

在视图中调用

@ViewBag.Name    
@ViewData["Name"]

A
Abhishek Gahlout

ViewBag 和 ViewData 是用于将信息从控制器传递到 ASP.Net MVC 中的视图的两种方式。使用这两种机制的目的是提供控制器和视图之间的通信。两者的寿命都很短,一旦发生重定向,即一旦页面从源页面(我们设置 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"] 

更多详情click here:


对不起,我投了反对票,但这个答案需要几段话才能说没有用。接受的答案中缺少的有用的东西是我从 rachelappel.com/… 中学到的句子“viewbag 是 viewdata 的动态包装器”