具有空模型的 renderpartial 传递了错误的类型
我有一个页面:
<%@ Page Inherits="System.Web.Mvc.View<DTOSearchResults>" %>
在上面有以下内容:
<% Html.RenderPartial("TaskList", Model.Tasks); %>
这是 DTO 对象:
public class DTOSearchResults
{
public string SearchTerm { get; set; }
public IEnumerable<Task> Tasks { get; set; }
这是部分内容:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Task>>" %>
当 Model.Tasks 不为空时,一切正常。 然而,当它为空时我得到:
传入字典的模型项是类型 'DTOSearchResults' 但此字典需要类型的模型项 'System.Collections.Generic.IEnumerable`1[任务]'。
我认为它一定不知道要使用哪个重载,所以我这样做(见下文)是明确的,但我仍然遇到同样的问题!
<% Html.RenderPartial("TaskList", (object)Model.Tasks, null); %>
我知道我可以通过检查 null 或什至不传递 null 来解决此问题,但这不是重点。 为什么会发生这种情况?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
安德鲁,我认为您遇到的问题是当您传递的模型为空时, RenderPartial 方法使用调用(视图)模型到部分视图的结果。您可以通过执行以下操作来解决这种奇怪的行为:
这有帮助吗?
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 的答案很好,但稍微短一点的是
这可以工作,因为 ViewDataDictionary 是保存模型的东西,它可以接受模型作为构造函数参数。 这基本上传递了一个“整个”视图数据字典,当然它只包含可能为空的模型。
@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.看起来,当您传入的模型的属性为 null 时,MVC 会故意恢复为“父”模型。 显然,MVC 引擎将空模型值解释为使用前一个模型值的意图。
这里有更多详细信息: ASP.NET MVC,强类型视图、部分视图参数故障
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
如果您不想丢失部分视图中以前的 ViewData,您可以尝试:
If you do not want to loose your previous ViewData in the partial view, you could try:
解决方案是创建一个如下所示的 HtmlHelper:
Partial(...)
在Partial(...)
之前匹配,非常方便且不会出现歧义错误编译时。就我个人而言,我发现很难理解这种行为 - 似乎很难想象这是设计选择?
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?
尽管这个问题已经得到解答,但我遇到了这个问题,并决定为我的项目解决这个问题,而不是使用 new ViewDataDictionary() 来解决它。
我创建了一组扩展方法:
https://github.com/q42jaap/PartialMagic.Mvc /blob/master/PartialMagic.Mvc/PartialExtensions.cs
我还添加了一些方法,如果模型为空,则不会调用部分,这将节省大量 if 语句。
我为 Razor 创建了它们,但其中一些也应该适用于 aspx 样式视图(使用 HelperResult 的视图可能不兼容)。
扩展方法如下所示:
还有用于
IEnumerable
如果您愿意,请随意使用它们。
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.
我的解决方法是:
My workaround to this is: