私はページを持っています:
<%@ Page Inherits="System.Web.Mvc.View<DTOSearchResults>" %>
そして、その上で、次の:
<% Html.RenderPartial("TaskList", Model.Tasks); %>
DTOオブジェクトは次のとおりです。
public class DTOSearchResults
{
public string SearchTerm { get; set; }
public IEnumerable<Task> Tasks { get; set; }
そして、ここに部分的です:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Task>>" %>
Model.Tasksがnullでない場合、すべてが正常に機能します。しかし、そのヌルが私が得るとき:
ディクショナリに渡されるモデルアイテムのタイプは「DTOSearchResults」ですが、このディクショナリには「System.Collections.Generic.IEnumerable`1 [Task]」タイプのモデルアイテムが必要です。
どのオーバーロードを使用するかを知らないはずだと思ったので、明示的にするためにこれを行いました(以下を参照)が、それでも同じ問題が発生します!
<% Html.RenderPartial("TaskList", (object)Model.Tasks, null); %>
Nullをチェックするか、nullを渡さなくてもこの問題を回避できることはわかっていますが、それはポイントではありません。なぜこうなった?
アンドリュー私はあなたが得ている問題は、あなたが渡すモデルがnullであるとき、部分ビューに呼び出し(ビュー)のモデルを使用するRenderPartialメソッドの結果だと思います。
<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary()); %>
それは役立ちますか?
@myandmycodeの答えは良いですが、少し短いものは
<% Html.RenderPartial("TaskList", new ViewDataDictionary(Model.Tasks)); %>
これは、ViewDataDictionary
がモデルを保持するものであり、コンストラクターパラメーターとしてモデルを受け入れることができるためです。これは基本的に「完全な」ビューデータディクショナリを渡しますが、これにはもちろんnullの可能性があるモデルのみが含まれます。
渡すモデルのプロパティがnullの場合、MVCは意図的に「親」モデルに戻ります。どうやらMVCエンジンは、以前のモデルを使用する意図としてnullモデル値を解釈します。
部分ビューで以前のViewDataを失いたくない場合は、次を試してください。
<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary(ViewData){Model = null});%>
解決策は、次のようなHtmlHelperを作成することです。
_public static MvcHtmlString Partial<T>(this HtmlHelper htmlHelper, string partialViewName, T model)
{
ViewDataDictionary viewData = new ViewDataDictionary(htmlHelper.ViewData)
{
Model = model
};
return PartialExtensions.Partial(htmlHelper, partialViewName, model, viewData);
}
_
Partial<T>(...)
は、Partial(...)
の前に一致するため、コンパイル時に非常に便利で、あいまいさのエラーがありません。
個人的には、振る舞いを理解するのが難しいと感じています-これをデザインの選択として想像するのは難しいようです?
これは回答されましたが、私はこれに出くわし、new ViewDataDictionary()
で回避するのではなく、この問題をプロジェクトで解決したいと思いました。
拡張メソッドのセットを作成しました: https://github.com/q42jaap/PartialMagic.Mvc/blob/master/PartialMagic.Mvc/PartialExtensions.cs
モデルがnullの場合、パーシャルを呼び出さないメソッドも追加しました。これにより、多くのifステートメントを節約できます。
Razor用に作成しましたが、そのうちのいくつかはaspxスタイルのビューでも機能するはずです(HelperResultを使用するビューはおそらく互換性がありません)。
拡張メソッドは次のようになります。
@* calls the partial with Model = null *@
@Html.PartialOrNull("PartialName", null)
@* does not call the partial if the model is null *@
@Html.PartialOrDiscard("PartialName", null)
IEnumerable<object>
モデル用のメソッドもあります。また、一部の結果をHTMLでラップできるようにするRazorラムダを使用して、破棄モデルを呼び出すこともできます。
必要に応じて自由に使用してください。
これに対する私の回避策は次のとおりです。
<% Html.RenderPartial("TaskList", Model.Tasks ?? new List()); %>