zoukankan      html  css  js  c++  java
  • MVC MVC3中 ViewBag、ViewData和TempData的使用和区别 【转】

    在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData。MVC3中保留了ViewData的使用。ViewBag 是动态类型(dynamic),ViewData 是一个字典型的(Dictionary)。
    它们的定义如下:

    [csharp] view plain copy
     
    1. public dynamic ViewBag { get; }  
    2. public ViewDataDictionary ViewData { get; set; }  

    控制器中代码:

    [csharp] view plain copy
     
    1. public ActionResult Index()  
    2. {  
    3.     ViewBag.Message_ViewBag = "I am viewbag";  
    4.     ViewData["Message_ViewData"] = "I am viewdata";  
    5.     return View();  
    6. }  

    视图代码:

    [html] view plain copy
     
    1. @{  
    2.     ViewBag.Title = "主页";  
    3. }  
    4.   
    5. <h2>@ViewBag.Message_ViewBag</h2>  
    6. <h2>@ViewData["Message_ViewData"]</h2>  

    运行图:


    当然我们可以在视图里面这样写:

    [html] view plain copy
     
    1. <h2>@ViewBag. Message_ViewData </h2>  
    2. <h2>@ViewData["Message_ViewBag "]</h2>  

    运行结果是一样的,这里表示它们俩是互通的。

    ViewBag和ViewData的区别:
    ViewBag 不再是字典的键值对结构,而是 dynamic 动态类型,它会在程序运行的时候动态解析。
    使用ViewBag
    控制器代码:

    [csharp] view plain copy
     
    1. public ActionResult Index()  
    2. {  
    3.     string[] items = new string[] { "one", "two", "three" };  
    4.     ViewBag.Items = items;// viewbag是一个新的dynamic关键字的封装器 //ViewData["Items"] = items;  
    5.     return View();  
    6. }  

    视图代码:

    [html] view plain copy
     
    1. <ul>  
    2.     @foreach (dynamic p in ViewBag.Items)  
    3.     {  
    4.         <li>The item is: @p</li>  
    5.     }  
    6. </ul>  


    其中dynamic p可以用var p或者string p取代
    执行效果:


    如果使用ViewData,则会出现如下错误:

    这时如果我们希望使用ViewData,就需要我们自己手动去将它强制转换为数组。通过调试,我们可以看到

    [csharp] view plain copy
     
    1. string[] items = new string[] { "one", "two", "three" };  
    2. ViewBag.Items = items;  
    3. ViewData["Items"] = items;  


    赋值后的ViewBag和ViewData都是字符串数组形式。如下图:

    只是ViewData为object型,而ViewBag为dynamic型。

    而dynamic型与object型的区别则是在使用时它会自动根据数据类型转换,而object型则需要我们自己去强制转换。

    比如上面我们遍历ViewBag.Items时,它自动根据数据类型转换,而ViewData则需要我们强制转换,如下:

    [html] view plain copy
     
    1. @foreach (string a in (string[])ViewData["Items"])  
    2. {  
    3.     <li>The item is: @a</li>  
    4. }  

    此外,通过转到定义我们可以看到:

    [csharp] view plain copy
     
    1. [Dynamic]  
    2. public dynamic ViewBag { get; }  
    3. public ViewDataDictionary ViewData { get; set; }  

    这里ViewBag只有get方法,没有set方法,但是我们在上面却给ViewBag赋值了。通过
    反编译发现ViewBag代码如下:

    [csharp] view plain copy
     
    1. [Dynamic]  
    2. public object ViewBag  
    3. {  
    4.     [return: Dynamic]  
    5.     get  
    6.     {  
    7.         Func<ViewDataDictionary> viewDataThunk = null;  
    8.         if (this._dynamicViewDataDictionary == null)  
    9.         {  
    10.             if (viewDataThunk == null)  
    11.             {  
    12.                 viewDataThunk = () => this.ViewData;  
    13.             }  
    14.             this._dynamicViewDataDictionary = new DynamicViewDataDictionary(viewDataThunk);  
    15.         }  
    16.         return this._dynamicViewDataDictionary;  
    17.     }  
    18. }  


    不难看出ViewBag返回的是_dynamicViewDataDictionary,继续跟踪发现_dynamicViewDataDictionary属于 DynamicViewDataDictionary类,其代码如下:

    [csharp] view plain copy
     
    1. internal sealed class DynamicViewDataDictionary : DynamicObject  
    2. {  
    3.     // Fields  
    4.     private readonly Func<ViewDataDictionary> _viewDataThunk;  
    5.   
    6.     // Methods  
    7.     public DynamicViewDataDictionary(Func<ViewDataDictionary> viewDataThunk);  
    8.     public override IEnumerable<string> GetDynamicMemberNames();  
    9.     public override bool TryGetMember(GetMemberBinder binder, out object result);  
    10.     public override bool TrySetMember(SetMemberBinder binder, object value);  
    11.   
    12.     // Properties  
    13.     private ViewDataDictionary ViewData { get; }  
    14. }  
    15. //其中有TryGetMember和TrySetMember方法,点开这两个方法:  
    16. public override bool TrySetMember(SetMemberBinder binder, object value)  
    17. {  
    18.     this.ViewData[binder.Name] = value;  
    19.     return true;  
    20. }  
    21.   
    22. public override bool TryGetMember(GetMemberBinder binder, out object result)  
    23. {  
    24.     result = this.ViewData[binder.Name];  
    25.     return true;  
    26. }  

    发现ViewBag其实本质就是ViewData,只是多了层Dynamic控制。所以,使用何种方式完全取决于你个人的爱好。

    TempData的使用
    同ViewData和ViewBag一样,TempData也可以用来向视图传递数据。只是ViewData和ViewBag的生命周期和View相同,只对当前View有用。而TempData则可以在不同的Action中进行传值,类似webform里的Seesion。如下:

    [csharp] view plain copy
     
    1. public ActionResult Index()  
    2. {  
    3.     ViewBag.hello = "hello,this is viewBag";  
    4.     ViewData["hi"] = "hi,this is viewData";  
    5.     TempData["abc"] = "this is tempdata";  
    6.     return View();  
    7. }  


    然后在About视图里面调用:

    [html] view plain copy
     
    1. <h2>关于</h2>  
    2. <p>  
    3.     @ViewBag.hello  
    4.     @ViewData["key"]  
    5.     @TempData["abc"]  
    6. </p>  


    页面效果如下:

    这里只获取到了TempData["abc"]的值,但是TempData的值在取了一次后则会自动删除,这时我再刷新页面,则TempData["abc"]为Null了。通过反编译查看代码,发现TempData数据在调用后则会自动删除。详情请看:http://blog.csdn.net/qq395537505/article/details/51983566

    其它视图注意事项:

    <li>The item is: @Html.Raw(p)</li>表示对p不进行HTML编码。

    控制器可以返回本视图,也可以返回其他视图:
    public ActionResult Index()
    {
    ViewBag.Message_ViewBag = "I am viewbag";
    ViewData["Message_ViewData"] = "I am viewdata";

    return View("About");
    }
    当我们需要返回指定完全不同目录结构中的视图时,可以这样使用~符号来提供视图的完整路径来返回: return View("~/Views/Home/About.cshtml");

    原文链接:http://blog.csdn.net/qq395537505/article/details/51983304

  • 相关阅读:
    SAP OPEN UI5 Step 8: Translatable Texts
    SAP OPEN UI5 Step7 JSON Model
    SAP OPEN UI5 Step6 Modules
    SAP OPEN UI5 Step5 Controllers
    SAP OPEN UI5 Step4 Xml View
    SAP OPEN UI5 Step3 Controls
    SAP OPEN UI5 Step2 Bootstrap
    SAP OPEN UI5 Step1 环境安装和hello world
    2021php最新composer的使用攻略
    Php使用gzdeflate和ZLIB_ENCODING_DEFLATE结果gzinflate报data error
  • 原文地址:https://www.cnblogs.com/alqscool/p/8288669.html
Copyright © 2011-2022 走看看