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
ViewData
Dictionary<string,object>
データがキーと値のペアの形式で保存される辞書ですViewData
。ViewData
コントローラーとビュー間、およびビューと部分ビュー間でデータを渡すために使用されます。その有効期間は、現在のビューのレンダリングが終了するまでです。ViewData
を使用するとオブジェクトが返されるためobject
、実際のプロパティまたは値の型を適用するにはキャストが必要です。渡されたデータがビューで文字列として使用される場合、c#
各オブジェクトにはビューToString
で自動的に呼び出されるメソッドがあるため、キャストは必要ありません。c#
直接の定義に加えて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 ページでは使用できません。
データの表示
- から派生しているため、や など
ViewDataDictionary
の利用可能な辞書属性があります。辞書内のキーは文字列であるため、スペースを使用できます。ContainsKey、Add、Remove
Clear
ViewData["Some Key With Whitespace"]
- 非型は
string
使用する前にビュー内でキャストする必要がありますViewData
。
ビューバッグ
- から派生している
DynamicViewData
ため、ドット表記を使用して(@ViewBag.SomeKey = <value or object>)
キャストせずに動的プロパティを作成できます。ViewBag 構文を使用すると、コントローラーとビューへの追加がはるかに高速になります。(実際にはほぼ) - 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、温度データ
TempData
System.Web.Mvc.TempDataDictionary
は から継承された型であり、Dictionary<string,object>
の辞書です。有効期間は、コントローラー内での開始から、 が読み取られる終了までです。たとえ別のコントローラー メソッドにリダイレクトされたとしても、 aが読み取られないTempData
限り、それは依然として存在します。TempData
アクセスしたページTempData
を更新すると、そのページが再度アクセスされTempData
、延長されていない有効期間TempData
は削除されます。TempData
通常は、アクション メソッド間でデータ (エラー メッセージなど) を渡すために使用されます。
1 回のアクセス後にオブジェクトを永続化したい場合はTempData
、コントローラーのメソッドでメソッドを呼び出すTempData.Keep
か、ビューでメソッドを使用してオブジェクトTempData.Peek
にアクセスする必要があります。ただし、このメソッドはリダイレクトされたビューでアクセスされるオブジェクトの存続期間を延長するTempData
ものではないことに注意してください。リダイレクトされたビューは、を使用して到達したビューです。TempData.Keep
TempData
RedirectXXX
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. セッション
session
Web.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>