Summary of ASP.NET MVC's Various Ways of Transferring Model to View(2)uuuuuuuuuuuuuuu

Keywords: ASP.NET Session

In ASP.NET MVC, view data can be accessed through ViewBag, ViewData and TempData, where ViewBag is Dynamic and ViewData is Dictionary.

They are defined as follows:

1 public dynamic ViewBag { get; }
2 public ViewDataDictionary ViewData { get; set; }

Controller code:

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

View code:

1 @{
2 ViewBag.Title = "homepage";
3 }
4 
5 <h2>@ViewBag.Message_ViewBag</h2>
6 <h2>@ViewData["Message_ViewData"]</h2>

Running Chart:

    

Of course, we can write in the view as follows:

1 <h2>@ViewBag.Message_ViewData </h2>
2 <h2>@ViewData["Message_ViewBag"]</h2>

The results are the same, which means they are interoperable.

 

The difference between ViewBag and ViewData:

Use ViewBag

ViewBag is no longer a dictionary key-value pair structure, but a dynamic type that dynamically parses when the program runs.
Controller code:

1 public ActionResult Index()
2 {
3     string[] items = new string[] {"one","two","three" };
4     ViewBag.Items = items;// viewbag It's a new one. dynamic Keyword wrapper         //ViewData["Items"] = items;
5     return View();
6 }

View code:

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

Where dynamic p can be replaced by var p or string p
Implementing effects:

    

 

Using ViewData

If ViewData is used, the following errors will occur:
    
At this point, if we want to use ViewData, we need to manually convert it into an array. Through debugging, we can see that

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

 

distinguish between

ViewBag and ViewData after assignment are both string arrays. The following picture:
    
ViewData is only object type, while ViewBag is dynamic type. The difference between dynamic and object is that it automatically converts according to the data type when it is used, while object requires us to force the conversion ourselves. For example, when we traverse ViewBag.Items above, it automatically converts according to the data type, while ViewData requires us to force the conversion, as follows:

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

In addition, by moving to the definition, we can see that:

1 [Dynamic]
2 public dynamic ViewBag { get; }
3 public ViewDataDictionary ViewData { get; set; }

ViewBag here has only get method and no set method, but we assign value to ViewBag above. ViewBag code is found by decompilation as follows:

 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 }

It is not difficult to see that ViewBag returns _dynamicViewDataDictionary, and continues to trace that _dynamicViewDataDictionary belongs to the DynamicViewDataDictionary class with the following code:

 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     Among them are TryGetMember and TrySetMember Method: Point out the two methods:
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     }
27 }

It is found that ViewBag is essentially ViewData, but with more layers of Dynamic control. So the way you use it depends entirely on your personal preferences.

 

Use of TempData

TempData, like ViewData and ViewBag, can also be used to pass data to views. It's just that ViewData and ViewBag have the same lifecycle as View and are only useful for the current View. TempData can pass values in different actions, similar to Seesion in webform. As follows:

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 }

Then call in the About view:

1 <h2>about</h2>
2 <p>
3 @ViewBag.hello
4 @ViewData["key"]
5 @TempData["abc"]
6 </p>

The effect of the page is as follows:
    
TempData["abc"] is only obtained here, but the value of TempData is automatically deleted after one fetch, and then I refresh the page, TempData["abc"] is Null.

Viewing the code through decompilation, TempData data is automatically deleted after invocation. For details, please refer to: http://www.cnblogs.com/tristanguo/archive/2009/04/06/1430062.html

TempData uses Session by default to store temporary data. TempData stored in TempData is valid only in one visit and will be deleted after one visit. This access refers to a request to the next request, because after the next request arrives, TempData stored in the Session is extracted and assigned to TempData, and then the data is deleted from the Session. Let's take a look at the ASP.NET MVC Preview 5 source code:

 
That is to say, TempData is only saved to the next request, and when the next request is completed, TempData will be deleted. Note that TempData is stored using Session, which corresponds to a specific user, so there is no concurrency problem.

If you want the data in TempData not to be deleted after accessing the next request, you can use the TempData.Keep() method.)

 

Other View Notes

<li>The item is: @Html.Raw(p)</li> means that P is not HTML coded.

Controller can return to this view or to other views as follows:

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

When we need to return a view in a specified entirely different directory structure, we can use the ~symbol to provide the complete path of the view to return:

1 return View("~/Views/Home/About.cshtml");

 

Reference link: https://www.cnblogs.com/bianlan/archive/2013/01/11/2857105.html

Posted by Jurik on Sat, 22 Dec 2018 21:51:05 -0800