私のビューダタはどのようにしてヌルになりますが、デバッガで拡張可能ですか?
-
26-10-2019 - |
質問
ビューをデバッグしながら、興味深い効果に出くわしました。シナリオは簡単に再現できます - 私はブレークポイントを持っています View
, 、私が追加する時計ウィンドウに ViewBag.ViewData
そして、値はです null
. 。ただし、追加する場合 ViewBag
オブジェクトを拡張して、私は見ることができます ViewData
そうではありません null
. 。また、それを正常に拡張して、そのプロパティを確認することもできます。
バグなのか、この動作を引き起こすのかを説明できますか?
編集
ViewBag.ViewData
実際には null
. 。たとえば、このコードがある場合:
if (ViewBag.ViewData == null)
{
<span>ViewBag.ViewData is null</span>
}
スパンを表示します。したがって、奇妙な部分は、時計ウィンドウで拡張してプロパティを見ることができるということです。
編集2
@Darin Dimitrovの答えに応えて - 私はこの動作をカスタムテストクラスで再現しようとしましたが、 RuntimeBinderException
私有財産にアクセスしようとするとき: 'SomeClass.SomeProperty' is inaccessible due to its protection level
:
public class SomeClass
{
private string SomeProperty;
}
dynamic dynamicObject = new SomeClass();
if (dynamicObject.SomeProperty == null)
{
Console.WriteLine("dynamicObject.SomeProperty is null");
}
この場合、アクセスするときに同じ例外を取得してはいけません ViewBag.ViewData
ビューで(ライン if (ViewBag.ViewData == null)
)?
解決
デバッガー/ウォッチウィンドウに表示されるのは プライベート ViewData
のプロパティ ViewBag
. 。ビューでテストを行うと、明らかにこのプライベートフィールドにアクセスできず、対応する公共財産がないためnullが得られます。
次に、ビューで次のテストを行います。
@if (null == ViewBag
.GetType()
.GetProperty("ViewData", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(ViewBag, null)
)
{
<span>ViewBag.ViewData is null</span>
}
そして、あなたはスパンを見ることができません。
もちろん、これはすべて非常に面白いですが、現実世界と適切にアーキテクチャされたASP.NET MVCアプリケーションを書くことに関しては両方とも ViewData
と ViewBag
場所がありません。これら2つは、ASP.NET MVCアプリケーション開発で私の最悪の敵です。
結論:常にビューモデルと強くタイプされたビューを使用して楽しんでください。
他のヒント
技術的な説明はありませんが、ViewBagがダイナミックだからだと思います。表現を時計を作るようなもので、式を実行せずに結果セットの内容が表示されません。
ViewBagは同じように動作していると思います。なぜなら、あなたはロードされていないプロパティに直接行くので、デバッガーを通してそれをやっているので、単にそのプロパティをロードしないことを決定します。
もちろん、私は完全に間違っている可能性があります:d
議論のためだけに、それはクイックウォッチまたは即時ウィンドウで同じことをしますか?
コードは常に特定のスコープ(クラス、方法、プライベートなど)の制限内で実行されますが、デバッガーにはそのような制限はありません
なぜviewbag.viewdataを参照しているのですか?ビューダタを直接参照するだけです。舞台裏でビューバッグがviewdataを使用しているため、これは機能する可能性があります。
これをテストした後、ViewBagは非公開のメンバーとして表示されます...これが私が期待するものです。 System.Web.MVC.DynamicViewDatadictionaryには、非公開会員ViewDataがあります