如何在ASP.NET MVC 中使用ViewBag,ViewData或TempData

这三个对象均可用作视图和控制器的属性。根据经验,您将使用ViewData,ViewBag和TempData对象来往于特定位置(例如,用于视图的控制器或视图之间的控制器)来回传输少量数据。ViewData和ViewBag对象在以下情况下均能正常工作:

  • 将查找数据的下拉列表合并到实体中
  • 像购物车这样的组件
  • 像用户个人资料小部件一样的小部件
  • 少量汇总数据

尽管TempData对象在一种基本情况下运行良好

  • 在当前和下一个HTTP请求之间传递数据

如果需要处理大量数据,报告数据,创建仪表板或处理多个不同的数据源,则可以使用功能更强大的ViewModel对象。请参阅我在ViewModels上的详细博客文章,以获取有关使用ViewModels的更多详细信息。

ViewData和ViewBag对象

  • ViewData
    • ViewData是您将数据放入其中的字典对象,然后该对象可用于视图。ViewData是ViewDataDictionary类的派生类,因此您可以通过熟悉的“键/值”语法进行访问。
  • ViewBag
    • ViewBag对象是ViewData对象的包装,它允许您为ViewBag创建动态属性。

ViewData和ViewBag对象都非常适合在控制器和视图之间访问额外的数据(即,在数据模型外部)。由于视图已经期望将特定的对象作为其模型,因此对额外数据的这种类型的数据访问,MVC将其实现为视图和控制器的属性,从而简化了对这些对象的使用和访问。 

下面的代码示例概述了ViewBag,ViewData和TempData对象的语法和用法,该示例填充了在面包店的主页中视图呈现的特色产品对象:

public ActionResult Index()
    {
        var featuredProduct = new Product
        {
            Name = "Special Cupcake Assortment!",
            Description = "Delectable vanilla and chocolate cupcakes",
            CreationDate = DateTime.Today,
            ExpirationDate = DateTime.Today.AddDays(7),
            ImageName = "cupcakes.jpg",
            Price = 5.99M,
            QtyOnHand = 12
        };
    
        ViewData["FeaturedProduct"] = featuredProduct;
        ViewBag.Product = featuredProduct;
        TempData["FeaturedProduct"] = featuredProduct;  
    
        return View();
    }
}

Index.cshtml视图通过使用与控制器中相同的语法访问代码来呈现Product对象。请注意,您必须强制转换ViewData和TempData对象,而不是ViewBag。

@using FourthCoffee.Models;
@{    
    ViewBag.Title = "Home Page";
    var viewDataProduct = ViewData["FeaturedProduct"] as Product;
    var tempDataProduct = TempData["FeaturedProduct"] as Product;                
}
<h2>Welcome to Fourth Coffee Bakery</h2>
<div>
    <a href="/Products">
    <img src=@Url.Content("\Content\Images\cake.jpg") alt="Fourth Coffee Bakery"/>    
    </a>
    <div>
        Todays Featured Product is!
        <br />
        <h
4>@ViewBag.FeaturedProduct.Name</h4>
        <h3>@viewDataProduct.Name</h3>
        <h2>@tempDataProduct.Name</h2>
    </div>
    @Html.ActionLink("Test Tempdata","Featured")
</div>

ViewBag对象使您可以向其添加动态属性,这使其成为非常通用的工具。

尽管在渲染此视图时所有三个都显示了某些内容,但是以这种方式使用TempData可能会很麻烦,这就是为什么……

临时数据

TempData是一个非常短暂的实例,您只应在当前请求和后续请求中使用它由于TempData以这种方式工作,因此您需要确定下一个请求将是什么,并且只有重定向到另一个视图时,您才能保证这一点。因此,唯一可以可靠使用TempData的方案是在重定向时。这是因为重定向会终止当前请求(并发送HTTP状态代码302 Object Moved)到客户端),然后在服务器上创建一个新请求以提供重定向视图。回顾先前的HomeController代码示例,这意味着TempData对象产生的结果可能与预期的不同,因为无法保证下一个请求的起源。例如,下一个请求可以源自完全不同的计算机和浏览器实例。

如下所述,使用TempData的语法与ViewData相同。

// TempData sample
public ActionResult Featured()
{
    var featuredProduct = new Product
    {
        Name = "Assorted Cupcakes",
        Description = "Delectable vanilla and chocolate cupcakes",
        CreationDate = DateTime.Today,
        ExpirationDate = DateTime.Today.AddDays(7),
        ImageName = "cupcakes.jpg",
        Price = 5.99M,
        QtyOnHand = 12
    };
 
    ViewData["FeaturedProduct"] = featuredProduct;
    ViewBag.Product = featuredProduct;
    TempData["FeaturedProduct"] = featuredProduct;
 
    //After the redirect, the ViewBag & ViewData objects are no longer available
    //Only TempData survives a redirect
 
    return new RedirectResult(@"~Featured");
}

但是,一旦控制器重定向,ViewBag和ViewData将包含空值。如果您在重定向后使用调试工具检查TempData对象,则会看到该对象已完全填充有特色产品。这是因为重定向是仅后续请求,因此只有它可以访问TempData对象,而不必担心。

@using FourthCoffee.Models;
@model FourthCoffee.Models.Product
@{
    ViewBag.Title = "Details";
    var featuredProduct = TempData["FeaturedProduct"] as Product;
}

常规Session对象是TempData对象的后备存储,并且与常规会话相比,它的销毁速度更快,即在后续请求之后立即销毁。由于其生存期短,因此非常适合将错误消息传递到错误页面。

格雷格(Greg shackles)的博客文章非常全面,涵盖了您需要了解的有关TempData的所有内容

既然您已经了解了如何以及何时使用ViewData,ViewBag和TempData对象,那么您可能想知道在使用更大的数据集或更复杂的场景时该怎么做。幸运的是,MVC可以处理这些通常需要的方案。

在ViewBag之外思考

您的需求可能需要您代表以下类型的数据,这些类型在使用ViewBag,ViewData或TempData对象时不太适合。MVC 3框架包含ViewModel对象,以供您在需要更多ViewData时使用。非常适合ViewModels的数据类型如下:

  • 主从数据
  • 更大的数据集
  • 复杂的关系数据
  • 报告和汇总数据
  • 仪表板
  • 来自不同来源的数据

在应用程序开发过程中,您可能会遇到这些或类似情况。

摘要

ViewData和ViewBag对象使您可以访问模型中附带的那些额外数据,但是对于更复杂的数据,您可以上移至ViewModel。另一方面,TempData专门用于处理HTTP重定向上的数据,因此请记住在使用TempData时要谨慎。

如何在ASP.NET MVC 中使用ViewBag,ViewData或TempData

上一篇:攻防世界 - Web进阶(一)


下一篇:deepin安装nodejs和npm