Several ways of passing values from Controller to View in MVC

Several ways of passing values ​​from Controller to View in MVC



1. ViewModel

ViewModel is a strongly typed class used to render ASP.NET MVC views, and can be used to pass data from one or more view models (that is, classes) or data tables. Think of it as a bridge connecting model, data and view. its 生命期为当前视图. The view model is strongly typed, so there are smart hints and static detection in VS.

Use ViewModel

First create a view model class for rendering the view:

public class Student
{
     
     
    public int ID {
     
      get; set; }
    public string Name {
     
      get; set; }
    public DateTime Birth {
     
      get; set; }
}

Define this class in your controller:

public IActionResult Index()
{
     
                 
    Student student=new Student()
    {
     
     
        ID = 1,
     Birth = new DateTime(2000,1,1),
        Name = "test"
    };
    return View(student);
}  

used in the view

Use at Razor视图the beginning to @modelspecify a strong type, and a view that uses @modelis called a strongly typed view, and a strongly typed view can get intellisense and static checking. If you don't use @mdoel, the following @Modelis a dynamic type, and you won't get smart hints and static checks.

At the same time, a strongly typed Model can use helper methods, while a weakly typed Model cannot use helper methods, because c# expression trees cannot contain dynamic operations.

Index view:

@model Student

<div>    
    @Html.DisplayNameFor(m=>m.ID)
    @Html.DisplayFor(m=>m.ID)
</div>
<div>
    Birth @Model.Birth
</div>
<div>
    Name @Model.Name
</div>

Strongly typed view:
insert image description here

insert image description here
Weakly typed views lack intellisense:

insert image description here
insert image description here

Two, ViewData

ViewDatais a Dictionary<string,object>dictionary of which data is stored in the form of key-value pairs ViewData. ViewDataUsed to pass data between controllers and views, and between views and partial views. Its lifetime is the end of the current view rendering. Since ViewDataan object is returned when using object, a cast is required to apply the actual type of property or value. No casting is required when the passed data is used in the view as a string, because c#each object has a method that is automatically called ToStringin the view.c#

ViewData
View
PartialView
ViewData
Controller
View
ViewData
PartialView

In addition to direct definitions ViewData[""], attribute definitions ASP.NET Coreare supported for properties in controllers .
[TempData]ViewData

However, ViewDatait cannot be used in cross-request situations, that is, the page after the jump cannot use the definition of the page before the jump ViewData, and the subsequent mentioned TempDatacan be used for cross-request data transfer.

Use ViewData to pass data between controller and view

public IActionResult ViewDataTest()
{
     
     
    ViewData["student"]=new Student()
    {
     
     
        ID = 1,
        Birth = DateTime.Now,
        Name = "test"
    };
    ViewData["Greeting"] = "Hello";
    return View();
} 

Use ViewData's data in the ViewDataTest view

@{
    Student student = ViewData["student"] as Student;
    ViewData["test"] = "test";
}

@ViewData["greeting"]
<div>ID: @student.ID</div>
<div>Name: @student.Name</div>
<div>Birth: @student.Birth</div>
<br/>
@Html.ActionLink("Test","Test")

Test method and view for testing across requests:

public IActionResult Test()
{
     
     
    return View();
}
@{
    ViewData["Title"] = "Test";
}

<h2>Test</h2>

@ViewData["test"]   

Directly use the properties of the data in ViewData:
insert image description here
When using between a view and a partial view ViewData, the definition in the partial view ViewDatawill not overwrite the original view ViewData. When passing between views and partial views , the main helper methods and markup helper methods ViewDataare used .PartialAsync<partial>

Using ViewData between views and partial views

public static Task<IHtmlContent> PartialAsync(this IHtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData)

The first parameter is passed in 部分视图名称, and the second parameter is passed in one ViewDataDictionary 对象. If the second parameter is not specified, the current view's will be ViewDatapassed to the partial view.

ViewDataTest2 view:

 <h2>ViewDataTest2</h2>
 @{
     
     
      ViewData["Student"] = new Student()
      {
     
     
          ID = 1,
          Birth = DateTime.Now,
          Name = "test"
      };
      ViewData["Greeting"] = "Good morning";
 }
 
 View: @ViewData["Greeting"]
 <br/>
 @await Html.PartialAsync("PartialView",new ViewDataDictionary(ViewData))
 
 View: @ViewData["Greeting"]

PartialView view:

@{
     
     
    Student student = ViewData["Student"] as Student;
}

Partial: @ViewData["Greeting"]
<hr/>
<div>ID: @student.ID</div>
<div>Name: @student.Name</div>
<div>Birth: @student.Birth</div>
<hr/>
@{
     
     
    ViewData["Greeting"] = "Good afternoon";
}

<div>Partial: @ViewData["Greeting"]</div>

Use the partial tag helper method:

About the partial markup helper method: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-2.1

When used, pass the name of the partial view for the name attribute and the name of the object view-datafor the attribute ViewDataDictionary:

<h2>ViewDataTest2</h2>
@{
     
     
    ViewData["Student"] = new Student()
    {
     
     
        ID = 1,
        Birth = DateTime.Now,
        Name = "test"
    };
    ViewData["Greeting"] = "Good morning";
}

View: @ViewData["Greeting"]
<br/>
@*@await Html.PartialAsync("PartialView",new ViewDataDictionary(ViewData))*@
<partial name="PartialView" view-data="ViewData" />
View: @ViewData["Greeting"]

The result is consistent with using PartialAsyncthe helper method.

3. ViewBag

ViewBagViewDatais a dynamic type that wraps ControllerBaseand inherits from , so it cannot be used in view pages ViewBag. Since ViewBagis a dynamic object, you can add arbitrary properties to it. Also because ViewBagis a dynamic type, you can directly call its properties to operate.

ViewBagThe difference between and ViewDatais:

  • It is not possible to pass a specific ViewBag in the view page.
  • Although ViewBag can be defined in the view to be used in the current view, it cannot be defined to be passed to partial views.

ViewBag is not available in Razor pages.

ViewData

  1. Derived from ViewDataDictionary, so it has available dictionary attributes like ContainsKey、Add、Removeand Clear. The keys in the dictionary are strings, so spaces are allowed.ViewData["Some Key With Whitespace"]
  2. Any non- stringtype must be cast in the view before it can be used ViewData.

ViewBag

  1. Derived from DynamicViewData, so it can use dot notation (@ViewBag.SomeKey = <value or object>)to create dynamic properties without casting. The ViewBag syntax makes adding to controllers and views much faster. (actually almost)
  2. Easier to check for NULL values.@ViewBag.Person?.Name
public IActionResult ViewBagTest()
{
     
     
    ViewBag.Student = new Student()
    {
     
     
		ID = 1,
		Birth = new DateTime(1997,1,1),
		Name = "test" 
    };
    return View();
}

ViewBagTest view:

 <h2>ViewBagTest</h2>
 
 <div>View: @(ViewBag.Student.ID+1)</div>
 
 @await Html.PartialAsync("_ViewBagPartial")

_ViewBagPartial view:

 <div>ID: @ViewBag.Student.ID</div>
 <div>Name: @ViewBag.Student.Name</div>
 <div>Birth: @ViewBag.Student.Birth</div>

4、TempData

TempDatais a System.Web.Mvc.TempDataDictionarytype inherited from and is a Dictionary<string,object>dictionary of . The lifetime is from the beginning of life in the controller TempDatato the end when the is read, even if redirected to another controller method, as long as a TempDatais not read, it still exists. TempDataRefreshing a page that has been visited will visit the page again TempData, and the unextended lifetime TempDatawill be deleted. TempDataTypically used to pass data (such as error messages) between action methods.

If you want to persist the object after one access TempData, you need to call the method in the controller's method TempData.Keep, or use the method in the view TempData.Peekto access TempDatathe object. However, it should be noted that the method will not extend the lifetime of the object TempData.Keepaccessed in the redirected view . TempDataA redirected view is RedirectXXXa view reached using .

Since TempDatathe saves itself in ASP.NETthe , it needs to be used with caution and can be problematic Sessionwhen hosting the application on multiple servers . TempDataTo solve this problem, you can choose to sessionassign all user requests to the same server within the lifetime of the server, or forward sessioninformation between servers.

In addition to using TempData[""]to TempDatadefine , you can also use to [TempData]modify attributes to TempDatadefine .

public IActionResult TempDataTest()
{
     
     
    TempData["error"] = "An error";
    TempData["greeting"] = "Hello";

    //将 TempData["error"] 生存期延长一次
    TempData.Keep("error");          

    return View();
}

public IActionResult ReceiveTempData()
{
     
     
    return View();
}

public IActionResult ReceiveTempData2()
{
     
     
    return View();
}

TempDataTest view:

 @{
     
     
     ViewData["Title"] = "TempDataTest";
 }
 
 <h2>TempDataTest</h2>
 
 <div>@TempData["error"]</div>
 
@*访问 TempData["greeting"] 并将 TempData["greetng"] 延长一次*@
 <div>@TempData.Peek("greeting")</div>
 <br/>
 <div>@Html.ActionLink("Another", "Index", "TempData")</div>
 @Html.ActionLink("ReceiveTempData","ReceiveTempData")

The ReceiveTempData view used to test across requests:

 @{
     
     
     ViewData["Title"] = "ReceiveTempData";
 }
 
 <h2>ReceiveTempData</h2>
 
 <div>@TempData["error"]</div>
 
 @*将 TempData["greetng"] 生命期延长一次*@
 <div>@TempData.Peek("greeting")</div>
 <br/>@Html.ActionLink("ReceiveTempData2", "ReceiveTempData2")

ReceiveTempData2 view:

 @{
     
     
     ViewData["Title"] = "ReceiveTempData2";
 }
 
 <h2>ReceiveTempData2</h2>
 
 <div>@TempData["error"]</div>
 <div>@TempData["greeting"]</div>

Another controller TempDataController:

public class TempDataController : Controller
{
     
     
    public IActionResult Index()
    {
     
     
        return View();
    }
}

The Index view for this controller:

@{
     
     
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<div>@TempData["error"]</div>

result:

insert image description here

Use redirection:

public IActionResult TempDataTest()
{
     
     
    TempData["error"] = "An error";
    TempData["greeting"] = "Hello";
    TempData.Keep("error");
    //return View();
    return RedirectToAction("ReceiveTempData");
}

Result:
insert image description here
TempData["error"] that should have been extended was not.

5. Session

sessionis Web.SessionStatea key-value object inherited from . Pass data between controllers, which can be used to pass data between controllers and views across request states. It is generally Sessionused to keep data for a specific user, but it is best not to place sensitive data in it. The lifetime lasts until it is explicitly destroyed by timeoutan event bound by the parameter, by calling the method, or by closing the browser. Clear、RemoveAll、AbandonIt is best to reduce Sessionthe use of because it is not reliable in server cluster environments and will always occupy server resources while in use.

SessionIt needs Startup.csto be configured in when using (configuration details).
insert image description here
Instructions:

Here we set the session expiration time to 5 seconds, which is calculated after each operation.

In the ConfigureServices method:

services.AddDistributedMemoryCache();
services.AddSession(options =>
{
     
     
	options.IdleTimeout = TimeSpan.FromSeconds(5);
	options.Cookie.HttpOnly = true;
});

In the Configure method:

 app.UseSession();
 app.UseMvc();

The order of middleware is important.

An exception occurs when is UseMvccalled after .UseSessionInvalidOperationException

In the default ASP.NET Core implementation, the methods for obtaining and setting byte stream, int and string data are provided in Session, respectively:

Get(ISession, String)
GetInt32(ISession, String)
GetString(ISession, String)
SetInt32(ISession, String, Int32)
SetString(ISession, String, String)

For convenience, implement a generic extension method of Setand respectively:GetISession

public static void Set<T>(this ISession session, string key, T value)
{
     
     
    session.SetString(key, JsonConvert.SerializeObject(value));
}

public static T Get<T>(this ISession session, string key)
{
     
     
    var value = session.GetString(key);
    return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}

In the controller:

  //用来获取和设置值的键
  public const string SessionKeyStudent = "_Student";

  public string AddSession()
  {
     
     
      if (HttpContext.Session.Get<Student>(SessionKeyStudent)==default(Student))
      {
     
     
          Student student=new Student()
          {
     
     
              Birth = new DateTime(1996,1,1),
              ID = 2,
              Name = "test"
          };
          HttpContext.Session.Set<Student>(SessionKeyStudent,student);
      }
      return "Session has been set";
  }

  public IActionResult SessionTest()
  {
     
     
      Student student = HttpContext.Session.Get<Student>(SessionKeyStudent) ?? new Student();           
      return View(student);
  }

SessionTest view:

@model Student
  @{
     
     
     ViewData["Title"] = "SessionTest";
 }
 
 <h2>SessionTest2</h2>

 <div>ID: @Model.ID</div>
 <div>Name: @Model.Name</div>
 <div>Birth: @Model.Birth</div>

6. Summary

insert image description here

back to the top


Guess you like

Origin blog.csdn.net/weixin_47410172/article/details/130764785