Частичное представление рендеринга с динамической моделью в движке просмотра 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 работает безупречно. Любые мысли?

Ответ 1

Только что нашел ответ, похоже, что представление, в котором я размещал код RenderPartial, имело динамическую модель, и поэтому MVC не смог выбрать правильный метод для использования. Приведение модели в RenderPartial к правильному типу устраняет проблему.

source: Использование Html.RenderPartial() в файлах ascx

Ответ 2

Вместо того, чтобы отбрасывать модель в вызове RenderPartial, и поскольку вы используете бритву, вы можете изменить первую строку в своем представлении из

@model dynamic

к

@model YourNamespace.YourModelType

Это имеет преимущество в работе над каждым вызовом @Html.Partial, который у вас есть в представлении, а также дает вам intellisense для свойств.

Ответ 3

Можно также назвать

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

Ответ 4

Есть еще одна причина, по которой это можно выбросить, даже если вы не используете динамический /ExpandoObject. Если вы делаете цикл, например:

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

В этом случае "var" вместо объявления типа будет вызывать ту же ошибку, несмотря на то, что RootFolder имеет тип "Папка". Изменяя var на фактический тип, проблема исчезает.

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

Ответ 5

Здесь можно передать динамический объект в представление (или частичное представление)

Добавьте следующий класс в ваше решение (используйте пространство имен 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());

Приветствия

Ответ 6

У меня была такая же проблема, и в моем случае это то, что я сделал

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

и в частичном виде

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

Ответ 7

Я играл с кодом С# и случайно нашел решение вашей проблемы, ха-ха

Это код для основного вида:

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

Тогда в Частичном представлении:

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

Это сработало для меня, я надеюсь, что это поможет вам тоже!