asp.net-mvc 带有 null 模型的 renderpartial 传递了错误的类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/650393/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:25:03  来源:igfitidea点击:

renderpartial with null model gets passed the wrong type

asp.net-mvcrenderpartial

提问by Andrew Bullock

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:

这是 DTO 对象:

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:

当 Model.Tasks 不为空时,一切正常。但是,当它为空时,我得到:

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]'.

传递到字典中的模型项的类型为“DTOSearchResults”,但该字典需要类型为“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?

我知道我可以通过检查 null 或什至不传递 null 来解决这个问题,但这不是重点。为什么会这样?

回答by meandmycode

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:

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

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

Does that help?

这有帮助吗?

回答by configurator

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

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

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

This works because the ViewDataDictionaryis 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.

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

回答by Zack

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.

看来,当您传入的模型的属性为空时,MVC 会有意恢复到“父”模型。显然,MVC 引擎将空模型值解释为使用前一个值的意图。

Slightly more details here: ASP.NET MVC, strongly typed views, partial view parameters glitch

这里有更多细节:ASP.NET MVC,强类型视图,部分视图参数故障

回答by Fran P

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

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

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

回答by Colin Breame

A solution would be to create a HtmlHelper like this:

一个解决方案是像这样创建一个 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);
}

The Partial<T>(...)matched before the Partial(...)so convenient and no ambiguity error when compiling.

Partial<T>(...)之前的匹配Partial(...),从而方便编译时没有歧义错误。

Personally I find it difficult to understand the behaviour - seems hard to imagine this as design choice?

我个人觉得很难理解这种行为 - 似乎很难想象这是设计选择?

回答by Jaap

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().

虽然这已经得到了回答,但我遇到了这个问题,并决定为我的项目解决这个问题,而不是使用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.

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

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).

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

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.

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

Feel free to use them if you like.

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

回答by h3n

My workaround to this is:

我的解决方法是:


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