web-dev-qa-db-ja.com

MVC Razor動的モデル、「オブジェクト」には「PropertyName」の定義が含まれていません

RazorビューエンジンでMVC 3を使用する。私はこのビューを持っています:

@model dynamic
@{
    var products = (List<ListItemBaseModel>)Model.Products;
    var threshold = (int)(Model.Threshold ?? 1);
    var id = Guid.NewGuid().ToString();
}

このコードを使用して別のビューから呼び出されます。

@Html.Partial("PartialViewName", new { Products = Model, Threshold = 5 })

両方のビューで、それらをデバッグしてモデルを見ると、正しいオブジェクトが含まれているようです。コードを実行すると、 "var products ="行に次のようなエラーが表示されます。

「オブジェクト」には「製品」の定義が含まれていません

誰が私にそのエラーが発生するのか説明できますか?繰り返しますが、デバッグモードでModelオブジェクトを見ると、問題なく見えます(製品としきい値の2つのプロパティがあります)

104
Ruud van Falier

ビューモデルとして匿名クラスのインスタンスを渡しますか?私はこれを試してみました(CSHTMLの動的ビューモデル)。匿名クラスを使用しているときと同じエラーが発生しましたが、名前付きクラスを作成するとうまくいきました。私は検索しましたが、これはどこにも記録されていません。

// error
return View(new { Foo = 1, Bar = "test" });

// worked
return View(new TestClass { Foo = 1, Bar = "test" });

編集#1:

David Ebbo によると、匿名型はinternalとしてコンパイルされるため、匿名型を動的型付きビューに渡すことはできません。 CSHTMLビューは別のアセンブリにコンパイルされるため、匿名型のプロパティにアクセスできません。

編集#2:

デビッド・エボは、この明確化のために投稿を編集しました。

注(2011年12月22日):MVC 3が動的を直接サポートするようになったため、以下の手法は不要になりました。この投稿は、実際、この機能をMVCに統合するきっかけとなりました!

149
Lucas

.NET 4.0では、匿名型はExpandoObjectsに簡単に変換できるため、すべての問題は変換自体のオーバーヘッドで修正されます。 こちら をご覧ください

40
Adaptabi

これは、内部プロパティを持つ匿名型とは関係ありません

それは 完全に可能 ビューから部分ビューに匿名型を渡す

今日同じ問題に遭遇しましたが、匿名型とその固有のinternalプロパティを渡す問題とは(直接)何の関係もありませんでした。

そのため、OPの質問に関連して、@ Lucasによる答えは無関係です-回避策は機能しますが

OPの質問では、匿名型が渡されていますアセンブリXのビューからアセンブリXのパーシャルに David Ebboが、匿名型の内部にあるプロパティについて概説した問題は重要ではありません。 ビュー用にコンパイルされた型、部分型および匿名型はすべて同じアセンブリに含まれています

それでは、ビューからパーシャルに匿名型を渡すことが突然失敗する原因は何ですか?

少なくとも 僕の 状況では、解決できないモデルタイプを指定する同じフォルダ内の別のビューが原因であることがわかりました。ビューは実行時にコンパイルされるため、実行時のビューのコンパイルの失敗は動的型のコンパイルの失敗を意味し、パーシャルはobjectを受け取るだけなので意味があります。何が起こっているのかすぐにはわかりませんが、OPの特定の例(および私の場合)では、これが問題の原因である可能性が高いです。

モデルの型は正しいが、ビューの別の部分がコンパイルされない場合、匿名型は同じようには影響されないことに注意してください。これは、Razorがビューのコンポーネントパーツの動的コンパイルをどのように分割するかにかかっています。

問題のあるビューを修正したら、ソリューション全体を再構築するか、修正されたかどうかを確認する前にプロジェクトをクリーンアップして再構築します。

再びこれに気づかないようにするには、これをcsprojファイルに追加して、Razorビューのコンパイル時コンパイルを有効にします。

<PropertyGroup>
    <MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>
25
joshcomley

ソリューションの任意の場所に次のクラスを追加します(System名前空間を使用するため、参照を追加せずにすぐに使用できます)-

    namespace System
    {
        public static class ExpandoHelper
        {
            public static ExpandoObject ToExpando(this object anonymousObject)
            {
                IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
                IDictionary<string, object> expando = new ExpandoObject();
                foreach (var item in anonymousDictionary)
                    expando.Add(item);
                return (ExpandoObject)expando;
            }

        }
    }

モデルをビューに送信したら、それをExpandoに変換します。

    return View(new {x=4, y=6}.ToExpando());
9

部分ビュー内でdynamicモデルタイプを使用する代わりに。

@Model.fooの代わりに@ViewData.Eval("foo")を使用して、匿名オブジェクト属性を呼び出すことができます。

その後、@Model dynamicをビューから削除できます。

Facebook Social Comments Integrationのビュー間でいくつかの属性を渡すときに、最近この問題に遭遇しました。サンプルコード:

Html.RenderPartial(@"Layouts/Partials/_Comments", new {currentUrl = Model.CurrentPage.GetAbsoluteUrl(), commentCount = 5 });

それから私の見解では、私はこのdivを持っていました:

<div class="fb-comments" data-href="@ViewData.Eval("currentUrl")" data-numposts="@ViewData.Eval("commentCount")" data-width="100%"></div>
4
JamesG

回避策を実装していないため、このエラーが発生するかどうかわかりません。部分ビューでも同じエラーが発生しました。解決策は、ビルドをクリーンアップして再構築することでした。構文が正しい場合、コードは機能するはずですが、カミソリエンジンはコードの変更を適切に更新していない可能性があります。

0
goran

辞書を使用してこの問題を回避しました。

 @Html.Partial("_Partial", new Dictionary<string, string> { { "Key1", "Val1" }, { "Key2", "Val2" }, { "Key3", "Val3" } });
0