zoukankan      html  css  js  c++  java
  • 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这个接口就行,但一般情况没有必要这么做。           

  • 相关阅读:
    聚集索引和非聚集索引的区别有哪些
    材料管理框架:一个共通的viewModel搞定所有的分页查询
    常用到的Linux命令
    Mybatis的使用中的一些不太注意的技巧
    Maven使用yuicompressor-maven-plugin打包压缩css、js文件
    Redis实现Mybatis的二级缓存
    zookeeper分布式协调服务的使用一
    Redis Cluster集群
    Spring+Struts2+Hibernate的整合
    SpringMVC,采用的是SpringJDBC
  • 原文地址:https://www.cnblogs.com/wenjiang/p/3123100.html
Copyright © 2011-2022 走看看