TempData,ViewData和ViewBag的比较

      学习ASP.NET有大约一个月了,一直都是半生不熟的,因为之前的很长时间都是在做java开发,没有时间静下来心来学习,加上ASP.NET的框架也很复杂,一时间也是看的昏头转向的,所以只能看到一点记录一点,慢慢积累,慢慢总结吧。

      Action向View传递数据很简单,方式也很多,最直接的就是我们向View传递Model,这本身就是MVC的意义所在。如果是显示一些消息,像是错误信息,可以使用ViewData:

public ActionResult Index()
{
     ViewData["message"] = "Hello Word!";
     return View();
}

      然后是视图:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <%: ViewData["message"]%>
</asp:Content>

      实际效果如:
     

      我们可以看到,ViewData就是一个字典,它存放的是键值对。

      既然Action可以向View传递数据,那么View是否可以修改数据然后再回传给Action呢?

      我们对代码这样修改:

public ActionResult Index()
{
      ViewData["message"] = "Hello Word!";
      return View();
}

public ActionResult About()
{
      string message = ViewData["message"] as string;
      if (message == "Hello")
      {
           ViewData["message2"] = "已经修改";
       }
      else
      {
           ViewData["message2"] = "没有修改";
      }
     return View();
}

       视图:
      

      为什么会这样?因为ViewData只会在一次HTTP请求中有效,当这次请求结束后,就会自动清空其值。为什么呢?

      因为ViewData的生命周期和所请求的View是一样的,仅对当前View有效。

      ViewBag也可以用来向视图传递数据:

public ActionResult Index()
{
     ViewBag.Message = "Hello, Word";
     return View();
}

      视图:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <%: ViewBag.Message%>
</asp:Content>

      ViewBag的使用就相当于ViewData。

     它跟ViewData一样,都是字典值,但是内在的实现却完全不一样。
      ViewBag最大的优点就是它不需要转型就可以使用它里面的值,但ViewData需要这样:

string message = ViewData["message"] as string;

      因为ViewBag存放的不是键值对,而是dynamic动态类型,这是ASP.NET MVC3新增的部分。动态类型非常强大,尤其是容器的使用。

      ViewBag就是封装了的ViewData,它是顺应C#4的dynamic关键字而诞生的。它可以让我们像是属性访问一样检索字典中的值,这样更加自然,这也是C#所倡导的:"可以读出来的代码"。

     ViewBag在使用上与ViewData并没有孰优孰劣的说法,但是可以肯定,ViewBag比ViewData要慢,但这个真心可以忽略。值得注意的是,ViewBag可以直接访问存储在ViewData里面的数据(因为它本来就只是封装了的ViewData)。但是,像是这样:

 ViewData["Message hehe"] = "Hello, Word";

     ViewBag就有心无力了。
     更加重要的是,ViewBag无法作为扩展方法的参数,因为编译器为了确保所选择的扩展方法是正确的,编译时必须知道参数的真正类型,所以,HTML辅助方法无法使用ViewBag。

     除了上面两种(其实是一种),还有一种方法,就是TempData。

     TempData也是字典,所以它的使用完全等同于ViewData,但两者之间还是存在很大的差异。

     TempData,顾名思义,就是临时数据。TempData保存在Session中,Controller每次请求的时候都会从Session中获取TempData,然后清除Session。基于这样的事实,在每次请求结束后,TempData的生命周期也就结束了。网上有一句话:TempData至多之只能通过一次Controller传递,假设我们的Controller是跳转到下一个Controller,以此类推,在最后一个Controlle相应的视图上,的确可以获得该TempData。但是,这并不是说TempData已经跨请求传递了,这依然只是一次请求,至于是否是跨Controller传递,我认为不是,所谓的通过Controller传递,是指将TempData传递给View,在上面的例子中,只有最后的Controller才会将该TempData传递给View,所以,TempData的确是只能通过一次Controller传递。

      TempData也可以在Action之间传递的,像是这样:

public ActionResult Index()
{
    TempData["message"] = "Hello";
    return View();
}

public ActionResult About()
{
    if ("Hello" == TempData["message"] as string)
    {
         TempData["message"] = "Hello,Word";
    }
    return View();
}

      但必须注意,要使该行为正确,也就是TempData能够被传递给另一个Action,Index操作对应的视图就不能使用TempData,因为一旦使用就相当于一次请求,那么TempData中的值就会被清空。

      TempData是存储在Session中,但这个并不是绝对的,我们可以改变TempData的存储地方,只要实现ITempDataProvider这个接口就行,但一般情况没有必要这么做。           

posted @ 2013-06-07 19:55  文酱  阅读(11420)  评论(6编辑  收藏  举报