I have a page:
<%@ Page Inherits="System.Web.Mvc.View<DTOSearchResults>" %>
And on it, the following:
<% Html.RenderPartial("TaskList", Model.Tasks); %>
Here is the DTO object:
public class DTOSearchResults
{
public string SearchTerm { get; set; }
public IEnumerable<Task> Tasks { get; set; }
and here is the partial:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Task>>" %>
When Model.Tasks is not null, everything works fine. However when its null I get:
The model item passed into the dictionary is of type 'DTOSearchResults' but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Task]'.
I figured it must not know which overload to use, so I did this (see below) to be explicit, but I still get the same issue!
<% Html.RenderPartial("TaskList", (object)Model.Tasks, null); %>
I know I can work around this by checking for null, or not even passing null, but that's not the point. Why is this happening?
My workaround to this is:
A solution would be to create a HtmlHelper like this:
The
Partial<T>(...)
matched before thePartial(...)
so convenient and no ambiguity error when compiling.Personally I find it difficult to understand the behaviour - seems hard to imagine this as design choice?
Andrew I think the problem you are getting is a result of the RenderPartial method using the calling (view)'s model to the partial view when the model you pass is null.. you can get around this odd behavior by doing:
Does that help?
@myandmycode's answer is good, but a slightly shorter one would be
This works because the
ViewDataDictionary
is the thing that holds the model, and it can accept a model as a constructor parameter. This basically passes an "entire" view data dictionary, which of course only contains the possibly-null model.Though this has been answered, I ran across this and decided I wanted to solve this issue for my project instead of working around it with
new ViewDataDictionary()
.I created a set of extension methods: https://github.com/q42jaap/PartialMagic.Mvc/blob/master/PartialMagic.Mvc/PartialExtensions.cs
I also added some methods that don't call the partial if the model is null, this will save a lot of if statements.
I created them for Razor, but a couple of them should also work with aspx style views (the ones that use HelperResult probably aren't compatible).
The extension methods look like this:
There are also methods for
IEnumerable<object>
models and the discard ones can also be called with a Razor lambda that allow you to wrap the partial result with some html.Feel free to use them if you like.
It appears that when the property of the Model you're passing in is null MVC intentionally reverts back to the "parent" Model. Apparently the MVC engine interprets a null model value as intent to use the previous one.
Slightly more details here: ASP.NET MVC, strongly typed views, partial view parameters glitch