MVC でコントローラーからビューに値を渡すいくつかの方法

MVC でコントローラーからビューに値を渡すいくつかの方法



1. ビューモデル

ViewModel は、ASP.NET MVC ビューをレンダリングするために使用される厳密に型指定されたクラスであり、1 つ以上のビュー モデル (クラス) またはデータ テーブルからデータを渡すために使用できます。これは、モデル、データ、ビューを接続するブリッジとして考えてください。その生命期为当前视图ビュー モデルは厳密に型指定されているため、VS にはスマート ヒントと静的検出があります。

ViewModel を使用する

まず、ビューをレンダリングするためのビュー モデル クラスを作成します。

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

コントローラーでこのクラスを定義します。

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

ビューで使用される

Razor视图最初に使用し@modelて強い型を指定します。これを使用するビューは@model強く型指定されたビューと呼ばれ、強く型指定されたビューはインテリセンスと静的チェックを取得できます。を使用しない場合@mdoel、以下は@Model動的型であるため、スマート ヒントと静的チェックは取得されません。

同時に、強く型指定されたモデルはヘルパー メソッドを使用できますが、C# 式ツリーには動的操作を含めることができないため、弱く型指定されたモデルはヘルパー メソッドを使用できません。

インデックスビュー:

@model Student

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

厳密に型指定されたビュー:
ここに画像の説明を挿入

ここに画像の説明を挿入
弱く型付けされたビューにはインテリセンスがありません。

ここに画像の説明を挿入
ここに画像の説明を挿入

2、ViewData

ViewDataDictionary<string,object>データがキーと値のペアの形式で保存される辞書ですViewDataViewDataコントローラーとビュー間、およびビューと部分ビュー間でデータを渡すために使用されます。その有効期間は、現在のビューのレンダリングが終了するまでです。ViewDataを使用するとオブジェクトが返されるためobject、実際のプロパティまたは値の型を適用するにはキャストが必要です。渡されたデータがビューで文字列として使用される場合、c#各オブジェクトにはビューToStringで自動的に呼び出されるメソッドがあるため、キャストは必要ありません。c#

ViewData
View
PartialView
ViewData
Controller
View
ViewData
PartialView

直接の定義に加えてViewData[""]ASP.NET Coreコントローラ内のプロパティの
[TempData]属性定義もサポートされていますViewData

ただし、ViewDataクロスリクエストの状況では使用できません。つまり、ジャンプ後のページはジャンプ前のページの定義を使用できません。ViewDataまた、後続の記述はTempDataクロスリクエストのデータ転送に使用できます。

ViewData を使用してコントローラーとビューの間でデータを渡します

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

ViewDataTest ビューで ViewData のデータを使用する

@{
    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")

リクエスト全体をテストするためのテスト方法とビュー:

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

<h2>Test</h2>

@ViewData["test"]   

ViewData のデータのプロパティを直接使用します。
ここに画像の説明を挿入
ビューと部分ビューの間で使用する場合ViewData、部分ビューの定義はViewData元のビューを上書きしませんViewDataビューと部分ビューの間を渡すときは、メインヘルパー メソッドとマークアップ ヘルパー メソッドViewDataが使用されます。PartialAsync<partial>

ビューと部分ビューの間で ViewData を使用する

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

最初のパラメータは で渡され部分视图名称、2 番目のパラメータは で渡されますViewDataDictionary 对象2 番目のパラメータが指定されていない場合は、現在のビューがViewData部分ビューに渡されます。

ViewDataTest2 ビュー:

 <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 ビュー:

@{
     
     
    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>

部分タグ ヘルパー メソッドを使用します。

部分マークアップ ヘルパー メソッドについて: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-2.1

使用する場合は、 name 属性に部分ビューの名前を渡し、view-data属性にオブジェクトの名前を渡します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"]

結果はPartialAsyncヘルパー メソッドを使用した場合と一致します。

3.ビューバッグ

ViewBagは、 をラップして継承するViewData動的型であるControllerBaseため、ビュー ページでは使用できませんViewBagは動的オブジェクトであるためViewBag、任意のプロパティを追加できます。また、ViewBag動的型であるため、そのプロパティを直接呼び出して操作することができます。

ViewBagとの違いは次のViewDataとおりです。

  • ビュー ページで特定の ViewBag を渡すことはできません。
  • ViewBag は、現在のビューで使用されるようにビュー内で定義できますが、部分ビューに渡すように定義することはできません。

ViewBag は Razor ページでは使用できません。

データの表示

  1. から派生しているため、や などViewDataDictionaryの利用可能な辞書属性があります辞書内のキーは文字列であるため、スペースを使用できます。ContainsKey、Add、RemoveClearViewData["Some Key With Whitespace"]
  2. 非型はstring使用する前にビュー内でキャストする必要がありますViewData

ビューバッグ

  1. から派生しているDynamicViewDataため、ドット表記を使用して(@ViewBag.SomeKey = <value or object>)キャストせずに動的プロパティを作成できます。ViewBag 構文を使用すると、コントローラーとビューへの追加がはるかに高速になります。(実際にはほぼ)
  2. NULL 値のチェックが容易になります。@ViewBag.Person?.Name
public IActionResult ViewBagTest()
{
     
     
    ViewBag.Student = new Student()
    {
     
     
		ID = 1,
		Birth = new DateTime(1997,1,1),
		Name = "test" 
    };
    return View();
}

ViewBagTest ビュー:

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

_ViewBag部分ビュー:

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

4、温度データ

TempDataSystem.Web.Mvc.TempDataDictionaryは から継承された型であり、Dictionary<string,object>の辞書です。有効期間は、コントローラー内での開始から、 が読み取られる終了までです。たとえ別のコントローラー メソッドにリダイレクトされたとしても、 aが読み取られないTempData限り、それは依然として存在します。TempDataアクセスしたページTempDataを更新すると、そのページが再度アクセスされTempData、延長されていない有効期間TempDataは削除されます。TempData通常は、アクション メソッド間でデータ (エラー メッセージなど) を渡すために使用されます。

1 回のアクセス後にオブジェクトを永続化したい場合はTempData、コントローラーのメソッドでメソッドを呼び出すTempData.Keepか、ビューでメソッドを使用してオブジェクトTempData.Peekにアクセスする必要があります。ただし、このメソッドはリダイレクトされたビューでアクセスされるオブジェクトの存続期間を延長するTempDataものではないことに注意してください。リダイレクトされたビューは、を使用して到達したビューです。TempData.KeepTempDataRedirectXXX

TempDataはそれ自体を に保存するASP.NETため、使用には注意が必要であり、Session複数のサーバーでアプリケーションをホストする場合にはTempData問題が発生する可能性があります。sessionこの問題を解決するには、サーバーの存続期間内にすべてのユーザー要求を同じサーバーに割り当てるか、sessionサーバー間で情報を転送するかを選択できます。

TempData[""]を使用してを定義するだけでなく、 を使用して を定義する属性を変更するTempDataこともできます[TempData]TempData

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 ビュー:

 @{
     
     
     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")

リクエスト全体のテストに使用される ReceiveTempData ビュー:

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

ReceiveTempData2 ビュー:

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

別のコントローラー TempDataController:

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

このコントローラーのインデックス ビュー:

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

<h2>Index</h2>

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

結果:

ここに画像の説明を挿入

リダイレクトを使用します。

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

結果:
ここに画像の説明を挿入
拡張されるべき TempData["error"] は拡張されませんでした。

5. セッション

sessionWeb.SessionStateは、 から継承されたキーと値のオブジェクトです。コントローラー間でデータを渡します。これは、リクエスト状態全体でコントローラーとビューの間でデータを渡すために使用できます。通常、Session特定のユーザーのデータを保持するために使用されますが、機密データをそこに置かないことをお勧めします。有効期間は、timeoutパラメーターによってバインドされたイベント、メソッドの呼び出し、またはブラウザーの終了Clear、RemoveAll、Abandonによって明示的に破棄されるまで続きます。Sessionサーバー クラスター環境では信頼性が低く、使用中は常にサーバー リソースを占有してしまうため、使用を減らすことが最善です。

使用時に設定がSession必要です(設定詳細)。説明書:Startup.cs
ここに画像の説明を挿入

ここでは、セッションの有効期限を 5 秒に設定します。これは各操作の後に計算されます。

ConfigureServices メソッド内:

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

Configure メソッド内:

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

ミドルウェアの順序は重要です。

の後にをUseMvc呼び出すUseSessionと例外が発生しますInvalidOperationException

既定の ASP.NET Core 実装では、バイト ストリーム、int、および文字列データを取得および設定するためのメソッドがそれぞれ Session で提供されます。

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

便宜上、Setと のGet汎用ISession拡張メソッドをそれぞれ実装します。

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);
}

コントローラー内:

  //用来获取和设置值的键
  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);
  }

セッションテストビュー:

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

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

6. まとめ

ここに画像の説明を挿入

トップに戻る


おすすめ

転載: blog.csdn.net/weixin_47410172/article/details/130764785