ASP.NET MVCに関する本を読んでいますが、次の例がどのように機能するのか疑問に思っています。
public class MyController : Controller
{
public ActionResult Index()
{
ViewBag.MyProperty = 5;
return View();
}
}
<h1>@ViewBag.MyProperty</h1>
これで、ViewBag
が動的オブジェクトであることがわかりました。そのため、プロパティを設定できます(動的オブジェクトについてはあまり知りませんが、動的オブジェクトを操作したことはありません)。コントローラーからViewBag
を取得しますが、直接何も渡しませんか?
ViewBag
はpublic
static
オブジェクトになる可能性があると思いましたが、それに対する変更はグローバルであり、ビューインスタンスに固有ではありません。
これが舞台裏でどのように機能するかについて詳しく説明していただけますか?
public class MyController : Controller
{
public ActionResult Index()
{
ViewBag.MyProperty = 5;
return View();
}
public ActionResult Index2()
{
ViewBag.MyProperty = 6;
return View();
}
}
ここで、最初にIndex
メソッドが呼び出され、次にIndex2
が呼び出されたとします。最終的に、ViewBag.MyProperty
の値は6(Index2
の値)になります。行うのは良いことではないと感じていますが、同時にデスクトップ開発の観点から考えていると感じています。 Webはステートレスであるため、ASP.NET MVCで使用する場合は問題になりません。 これは事実ですか?
ViewBag
はControllerBase
のプロパティで、すべてのコントローラーが継承する必要があります。これはdynamic
オブジェクトです。そのため、コンパイル時にエラーが発生することなく、新しいプロパティを追加できます。
static
ではなく、オブジェクトのメンバーです。リクエストの有効期間中、コントローラーインスタンスが作成および破棄されるため、値の上書きなどの「同時実行性」の問題は発生しません。
View
(およびそのバリアント)メソッドもstatic
ではありません。これは、ビューがViewBag
値を受け取る方法です。ビューのレンダリングプロセス中、コントローラーインスタンスにはViewBagインスタンスもあります。
ControllerBase classを分析する場合、ViewBagプロパティは、ソースをより見やすくするためにViewDataプロパティの「プロキシ」であることがわかります。 (Scott HanselmanがPhil Haackからインタビューを受け、PhilがViewDataへのショートカットとしてViewBagプロパティを導入し、角括弧と引用符を繰り返す必要をなくしたことさえ覚えています)。 ViewBag
プロパティはdynamic
オブジェクトとして公開されますが、ViewDataと直接連携する DynamicViewDataDictionary クラスを実装します。
Controller クラスのソースコードを見ると、このメソッドを見つけることができます:
_protected internal virtual ViewResult View(string viewName, string masterName, object model)
_
基本的に、コントローラーからreturn View();
を呼び出すと、コントローラーからViewDataをコンストラクターに渡すActionResult
クラスの新しいインスタンスが作成されます。 ActionResult
のインスタンスは、特定のビューエンジン(ASPX、Razor)に渡されるため、問題のビューをレンダリングするために使用できます。
ViewBag/ViewDataをpublic staticにすることは有害です。 MVCアプリケーションへの各Web要求は、コントローラーの新しいインスタンスを作成します。パブリックスタティックとしてViewData/ViewBagがある場合、2人の同時ユーザーがViewBag/ViewDataから同じデータを共有します。
ここ はビデオです。 ViewBag(以前のViewModel)に関する議論は04:05に始まります
ViewBag
は ControllerBase
のプロパティです。次のように定義されます。
public Object ViewBag { get; }
この署名は実際には間違っていることに注意してください。ソースコードは実際には次のようになります。
public dynamic ViewBag {
get {
if (_dynamicViewDataDictionary == null) {
_dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
}
return _dynamicViewDataDictionary;
}
}
_dynamicViewDataDictionary
はExpandoObjectです。実行時にプロパティを追加できます。その有効期間は、コントローラーの有効期間と同じです。これは、HTTP要求の有効期間です。