Передача нулевого дочернего объекта из родительского объекта в частичное представление - PullRequest
7 голосов
/ 17 марта 2010

У меня есть объект, который содержит модели для моего веб-приложения ASP.NET MVC. Модель, которая передается в представление, имеет подмодели для «гаджетов» в этом конкретном представлении. Каждая из этих подмоделей передается в частичное представление (гаджет).

Проблема в том, что в модели вида у меня пустая модель. Смотрите пример ниже.

Просмотр модели:

public class FooBarHolder()
{
     public FooBar1 FooBar1 { get; set; }
     public FooBar2 FooBar2 { get; set; }
}

Мы передаем FooBarHolder в представление и внутри представления делаем вызовы, такие как

<% Html.RenderPartial("Foo", Model.FooBar1); %>
<% Html.RenderPartial("Foo2", Model.FooBar2); %>

Теперь скажем, например, что Model.FooBar2 был нулевым. Что я испытываю в строго типизированном частичном представлении, так это ошибка, которая говорит: «Это представление ожидало модель типа FooBar2, но получило модель типа FooBarHolder».

Почему это происходит вместо того, чтобы просто принимать нулевое значение?

Ответы [ 3 ]

8 голосов
/ 17 марта 2010

Вот как работает метод RenderPartial (я знаю, что должен был быть задокументирован, опубликован в блоге и т. Д., Мне тоже это кажется немного странным). Если вы не укажете модель или передадите null, она будет использовать модель родительской страницы. Чтобы избежать этого, вы можете использовать оператор объединения нулей:

<% Html.RenderPartial("Foo", Model.FooBar1 ?? new Foo()); %>

И если вам действительно интересно, как это реализовано, есть выдержка из соответствующих частей исходного кода ASP.NET MVC 2:

// Renders the partial view with an empty view data and the given model
public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model) {
    htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
}

internal virtual void RenderPartialInternal(string partialViewName, ViewDataDictionary viewData, object model, TextWriter writer, ViewEngineCollection viewEngineCollection) {
    if (String.IsNullOrEmpty(partialViewName)) {
        throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");
    }

    ViewDataDictionary newViewData = null;

    if (model == null) {
        if (viewData == null) {
            newViewData = new ViewDataDictionary(ViewData);
        }
        else {
            newViewData = new ViewDataDictionary(viewData);
        }
    }
    else {
        if (viewData == null) {
            newViewData = new ViewDataDictionary(model);
        }
        else {
            newViewData = new ViewDataDictionary(viewData) { Model = model };
        }
    }

    ViewContext newViewContext = new ViewContext(ViewContext, ViewContext.View, newViewData, ViewContext.TempData, writer);
    IView view = FindPartialView(newViewContext, partialViewName, viewEngineCollection);
    view.Render(newViewContext, writer);
}

Обратите внимание, как обрабатывается случай нулевой модели.

2 голосов
/ 30 сентября 2015

Чтобы избежать передачи родительской модели, когда дочерняя модель пуста, используйте этот трюк:

@Html.Partial("Child", null, new ViewDataDictionary<ChildType>(childInstance/*this can be null*/))

Кредит причитается ...

1 голос
/ 20 декабря 2010

Мой обходной путь для этой странной «функции» (или, может быть, ошибки):

<% Html.RenderPartial(
    "Foo2", 
    new ViewDataDictionary(ViewData) { Model = Model.FooBar2 }
); %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...