web-dev-qa-db-ja.com

RazorビューエンジンとASP.NET MVC 3の動的モデルで部分ビューをレンダリングする

モデルタイプが次のように指定されている部分ビューをレンダリングしようとすると、

@model dynamic

次のコードを使用して:

@{Html.RenderPartial("PartialView", Model.UserProfile);}

次の例外が発生します。

'System.Web.Mvc.HtmlHelper<dynamic>' has no applicable method named 'RenderPartial' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

ただし、.aspxファイル内の同じコードは問題なく機能します。何かご意見は?

63
Diego

答えを見つけたところ、RenderPartialコードを配置したビューには動的モデルがあり、MVCは使用する正しい方法を選択できなかったようです。 RenderPartial呼び出しでモデルを正しいタイプにキャストすると、問題が修正されました。

ソース: ascxファイルでHtml.RenderPartial()を使用

54
Diego

RenderPartial呼び出しでモデルをキャストする代わりに、かみそりを使用しているため、ビューの最初の行を

@model dynamic

@model YourNamespace.YourModelType

これには、すべての@Html.Partialビューにある呼び出し、およびプロパティのインテリセンスも提供します。

26
juan

として呼び出すこともできます

@Html.Partial("_PartialView", (ModelClass)View.Data)
17
Tom

Dynamic/ExpandoObjectを使用していない場合でも、これがスローされる可能性がある別の理由があります。次のようなループを実行している場合:

@foreach (var folder in ViewBag.RootFolder.ChildFolders.ToList())
{
    @Html.Partial("ContentFolderTreeViewItems", folder)
}

その場合、RootFolderが「Folder」型であるにもかかわらず、型宣言の代わりに「var」が同じエラーをスローします。varを実際の型に変更すると、問題はなくなります。

@foreach (ContentFolder folder in ViewBag.RootFolder.ChildFolders.ToList())
{
    @Html.Partial("ContentFolderTreeViewItems", folder)
}
7
J Wynia

動的オブジェクトをビュー(または部分ビュー)に渡す方法は次のとおりです。

ソリューションの任意の場所に次のクラスを追加します(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());

乾杯

3

私は同じ問題を抱えていたと私の場合、これは私がやったことです

@Html.Partial("~/Views/Cabinets/_List.cshtml", (List<Shop>)ViewBag.cabinets)

および部分ビューで

@foreach (Shop cabinet in Model)
{
    //...
}
1

私はC#コードで遊んでいて、あなたの問題の解決策を誤って見つけました

これは、プリンシパルビューのコードです。

`@model dynamic 
 @Html.Partial("_Partial", Model as IDictionary<string, object>)`

次に、部分ビューで:

`@model dynamic 
 @if (Model != null) { 
   foreach (var item in Model) 
   { 
    <div>@item.text</div> 
   } 
  }`

それは私のために働いた、これがあなたにも役立つことを願っています!!

0
Alan