具有空模型的 renderpartial 传递了错误的类型

发布于 2024-07-15 07:39:13 字数 949 浏览 11 评论 0原文

我有一个页面:

<%@ 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

困倦 2024-07-22 07:39:13

安德鲁,我认为您遇到的问题是当您传递的模型为空时, RenderPartial 方法使用调用(视图)模型到部分视图的结果。您可以通过执行以下操作来解决这种奇怪的行为:

<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary()); %>

这有帮助吗?

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:

<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary()); %>

Does that help?

傾城如夢未必闌珊 2024-07-22 07:39:13

@myandmycode 的答案很好,但稍微短一点的是

<% Html.RenderPartial("TaskList", new ViewDataDictionary(Model.Tasks)); %>

这可以工作,因为 ViewDataDictionary 是保存模型的东西,它可以接受模型作为构造函数参数。 这基本上传递了一个“整个”视图数据字典,当然它只包含可能为空的模型。

@myandmycode's answer is good, but a slightly shorter one would be

<% Html.RenderPartial("TaskList", new ViewDataDictionary(Model.Tasks)); %>

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.

此岸叶落 2024-07-22 07:39:13

看起来,当您传入的模型的属性为 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

岁月打碎记忆 2024-07-22 07:39:13

如果您不想丢失部分视图中以前的 ViewData,您可以尝试:

<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary(ViewData){Model = null});%>

If you do not want to loose your previous ViewData in the partial view, you could try:

<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary(ViewData){Model = null});%>
残疾 2024-07-22 07:39:13

解决方案是创建一个如下所示的 HtmlHelper:

public static MvcHtmlString Partial<T>(this HtmlHelper htmlHelper, string partialViewName, T model)
{
    ViewDataDictionary viewData = new ViewDataDictionary(htmlHelper.ViewData)
    {
        Model = model
    };
    return PartialExtensions.Partial(htmlHelper, partialViewName, model, viewData);
}

Partial(...)Partial(...) 之前匹配,非常方便且不会出现歧义错误编译时。

就我个人而言,我发现很难理解这种行为 - 似乎很难想象这是设计选择?

A solution would be to create a HtmlHelper like this:

public static MvcHtmlString Partial<T>(this HtmlHelper htmlHelper, string partialViewName, T model)
{
    ViewDataDictionary viewData = new ViewDataDictionary(htmlHelper.ViewData)
    {
        Model = model
    };
    return PartialExtensions.Partial(htmlHelper, partialViewName, model, viewData);
}

The Partial<T>(...) matched before the Partial(...) 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?

挖个坑埋了你 2024-07-22 07:39:13

尽管这个问题已经得到解答,但我遇到了这个问题,并决定为我的项目解决这个问题,而不是使用 new ViewDataDictionary() 来解决它。

我创建了一组扩展方法:
https://github.com/q42jaap/PartialMagic.Mvc /blob/master/PartialMagic.Mvc/PartialExtensions.cs
我还添加了一些方法,如果模型为空,则不会调用部分,这将节省大量 if 语句。

我为 Razor 创建了它们,但其中一些也应该适用于 aspx 样式视图(使用 HelperResult 的视图可能不兼容)。

扩展方法如下所示:

@* calls the partial with Model = null *@
@Html.PartialOrNull("PartialName", null)
@* does not call the partial if the model is null *@
@Html.PartialOrDiscard("PartialName", null)

还有用于 IEnumerable模型的方法,并且丢弃的方法也可以使用 Razor lambda 调用,允许您用一些 html 包装部分结果。

如果您愿意,请随意使用它们。

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:

@* calls the partial with Model = null *@
@Html.PartialOrNull("PartialName", null)
@* does not call the partial if the model is null *@
@Html.PartialOrDiscard("PartialName", null)

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.

何处潇湘 2024-07-22 07:39:13

我的解决方法是:


<% Html.RenderPartial("TaskList", Model.Tasks ?? new List()); %>

My workaround to this is:


<% Html.RenderPartial("TaskList", Model.Tasks ?? new List()); %>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文