Loading

ViewData、ViewBag、TempData、Session的区别与联系

简介

这篇文章是我在学习ASP.NET MVC程序传值方式梳理总结的笔记。在ASP.NET MVC中,页面间和Controller与View之间主要有以下几种小量数据传值方式, ViewDataViewBagTempDataSession变量。 我们是幸运的,微软提供给了我们这么多传值方法,但选择越多越让人抓狂,这些技术每一种都有自己的优点和缺点,我应该何时使用哪一种传值方式呢?

正文

上面的这四种方法中,ViewData和ViewBag其实是一回事, ViewBag其实是对ViewData的封装, 其内部其实是使用ViewData实现数据存储的。唯一的不同点是,ViewBag可以存储动态类型(dynamic)的变量值, 而ViewData只能存储String Key/Object Value字典数组。 所以我们可以将这四种方法归为三大类, ViewData和ViewBag, TempData, Session。

ViewData["Message"] = "Hello ASP.NET MVC";
// Or
ViewBag.Message = "Hello ASP.NET MVC";

TempData也是一个String Key/Object Value字典数组。 和ViewData与ViewBag不同的是其所存储的数据对象的生命周期。 如果页面发生了跳转(Redirection),ViewBag和ViewData中的值将不复存在, 但是TempData中的值依然还在。 换句话讲, ViewBag和ViewData存储的值的生命周期只有在从Controller到View中, 而TempData中的数据不仅在从Controller到View中有效,在不同的Action之间或者从一个页面跳转到另一页面(Controller to Controller)后依然有效。

TempData["Message"] = "Hello ASP.NET MVC";

Session其实和ViewData类似,也是一个String Key/Object Value字典数组。但是,Session是存储在客户端的Cookies中,所以它的生命周期是最长的。 但是,正因为其存储的客户端, 所以必须确保没有敏感机密的信息存储其中

Session["Message"] = "Hello ASP.NET MVC";

下面我们对每一个传值方法的特点进行以下总结。

ViewData

  • ViewData是一个继承自ViewDataDictionary类的Dictionary对象。
  • ViewData用来从Controller向对应的View传递值。
  • ViewData的只在当前当前的请求中有效,生命周期和View相同,其值不能在多个请求中共享。
  • 在重定向(redirection)后,ViewData中存储的变量值将变为null。
  • 在取出ViewData中的变量值是,必须进行合适的类型转换(隐式或显式)和空值检查。

下面我们来看一个简单的例子,演示一下如何使用ViewData来从Controller向View传值。

public ActionResult Index()
{
    ViewData["Message"] = "This is a message from ViewData";

    return View();
}

然后,我们从视图中取出这个变量,

执行后,你将会在浏览器中看到如下的结果,

可能你注意到了,我在从ViewData中取出变量Message时并没有对其进行类型转换,那时因为我们存储的是一个简单类型的变量值。假如存储的是复杂对象,在取出是必须进行类型转换。

综上, ViewData更适合从Controller向View传递简单对象数据时使用。

ViewBag

  • ViewBag是一个动态类型变量(dynamic),这是C# 4.0引入的新特性,变量类型会在运行时进行解析。
  • ViewBag基本上是ViewData的包装,也是用来从Controller向View来传递值的。
  • ViewBag也只在当前的请求中有效。
  • 在重定向(redirection)后,ViewBag中存储的变量值将变为null
  • 因为ViewBag是动态类型,所以我们在取得其值时,不需要进行类型转换。

同样,我们通过一个简单的例子来演示一下如何利用ViewBag从Controller向View传递数据。

public ActionResult Index()
{
    ViewBag.Message = "This is a message from ViewBag";

    return View();
}

然后,在视图中取出数据并显示,

最后,执行程序,你将会在浏览器中看到如下结果,

综上, ViewBag更适合从Controller向View传递复杂对象数据时使用, 因为取出存储在其中的数据变量时无需进行类型转换。

TempData

  • TempData是一个继承自TempDataDictionary类的字典对象,它默认情况下是基于Session存储机制之上的。(备注: 你也可以让你的TempData基于其他存储机制之上, 我们可以提供我们自定义的ITempDataProvider来完成,具体可以参见: Session-less Controllers and TempData in ASP.NET MVC)
  • TempData是用来在多个Actions或从当前请求向子请求, 页面发生了重定向(Redirection)时传递共享数据。
  • 只有在目标视图(View)完全加载后才有效。
  • 在取出TempData存储的变量值时,必须进行合适的类型转换(隐式或显式)和空值检查。

下面,我们透过一个例子来演示一下如何在两个Action方法中传递数据。

首先,创建一个客户Model类,如下:

public class Customer
{
    public int Id { get; set; }
    public string Code { get; set; }
    public double Amount { get; set; }
}

然后,在Controller中加入如下代码:

public ActionResult DisplayCustomer1()
{
    Customer customer = new Customer
    {
        Id = 1001,
        Code = "100101",
        Amount = 100
    };

    TempData["OneCustomer"] = customer;

    return RedirectToAction("DisplayCustomer2");
}

public ActionResult DisplayCustomer2()
{
    Customer customer = TempData["OneCustomer"] as Customer;

    return View(customer);
}

最后,创建一个强类型视图(Strong Typed View)来显示客户信息。

执行程序,浏览器中会显示如下结果:

综上, TempData主要用在需要在多个Actions或者页面重定向时共享传递数据时使用。

Session

  • Session也是ASP.NET MVC程序传递值的一种方式,但与TempData不同,用户的整个会话中Session都不会过期。
  • Session在同一用户会话过程中的所有请求中有效,比如,刷新页面。
  • Session中的值也需要进行类型转换(隐式或显式)和非空检查。

我们仍然使用上面的这个例子,假如我们不用TempData而是使用Session, 也可以得到同样的结果。

public ActionResult DisplayCustomer1()
{
    Customer customer = new Customer
    {
        Id = 1001,
        Code = "100101",
        Amount = 100
    };

    Session["OneCustomer"] = customer;

    return RedirectToAction("DisplayCustomer2");
}

public ActionResult DisplayCustomer2()
{
    Customer customer = Session["OneCustomer"] as Customer;

    return View(customer);
}

Session的生命周期是最长的,但是它默认使用的是Cookies来存储数据,所以使用的时候必须注意数据保密的问题。

综上, Session主要用在需要在多个Controllers, Actions and Views共享数据(非敏感数据)时使用。

图说传递方式的生命周期

Maintains data between ViewData/ViewBag TempData ( For single request) Session
Controller to Controller No Yes Yes
Controller to View Yes Yes Yes
View to Controller No No Yes

后记

本文试图通过介绍ASP.NET MVC程序中传递小量数据的几种机制的优缺点和适用场景。 本文只是一篇学习笔记,笔者初学ASP.NET MVC, 理解难免有偏差, 如有错误, 还望指正。

参考资料:

ASP.NET MVC学习笔记系列

posted @ 2014-04-01 12:28  光脚码农  阅读(10800)  评论(3编辑  收藏  举报