ASP.NET MVC、强类型视图、部分视图参数故障

发布于 2024-07-25 08:32:19 字数 487 浏览 7 评论 0原文

如果我得到的视图继承自:

System.Web.Mvc.ViewPage<Foo>

Where Foo 有一个类型为 string 的属性 Bar
视图想要渲染继承自:的强类型部分视图,

System.Web.Mvc.ViewUserControl<string>  

如下所示:

Html.RenderPartial("_Bar", Model.Bar);%>

那么为什么它会抛出这个:

传入字典的模型项的类型为“Foo”
但该字典需要“System.String”类型的模型项。

当 bar 未初始化时?

更具体地说:为什么它传递 Foo,它应该在哪里传递 null?

If i got view which inherits from:

System.Web.Mvc.ViewPage<Foo>

Where Foo has a property Bar with a type string
And view wants to render strongly typed partial view which inherits from:

System.Web.Mvc.ViewUserControl<string>  

like this:

Html.RenderPartial("_Bar", Model.Bar);%>

Then why it will throw this:

The model item passed into the dictionary is of type 'Foo'
but this dictionary requires a model item of type 'System.String'.

when bar is not initialized?

More specific: why it passes Foo, where it should pass null?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

淡忘如思 2024-08-01 08:32:19

正如@Dennis 指出的,如果模型值为空,它将使用视图中的现有模型。 这样做的原因是支持使用仅包含分部视图名称的签名调用分部视图并使其重用现有模型的能力。 在内部,所有 RenderPartial 帮助器都遵循单个 RenderPartialInternal 方法。 获得该方法重用现有模型的方法是传入模型的空值(仅采用视图名称的签名就是这样做的)。 当您将 null 值传递给同时包含视图名称和模型对象的签名时,您实际上是在复制仅采用视图名称的方法的行为。

这应该可以解决您的问题:

<% Html.RenderPartial( "_Bar", Model.Bar ?? string.Empty ) %>

As @Dennis points out, if the model value is null, it will use the existing model from the view. The reason for this is to support the ability to call a partial view using a signature that contains only the partial view name and have it reuse the existing model. Internally, all of the RenderPartial helpers defer to a single RenderPartialInternal method. The way you get that method to reuse the existing model is to pass in a null value for the model (which the signature that takes only a view name does). When you pass a null value to the signature containing both a view name and a model object, you are essentially replicating the behavior of the method that takes only the view name.

This should fix your issue:

<% Html.RenderPartial( "_Bar", Model.Bar ?? string.Empty ) %>
万劫不复 2024-08-01 08:32:19

查看 ASP.NET MVC 源代码(HtmlHelper.cs -> RenderPartialInternal 方法 -> 第 258 行):

...

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

...

这正是您的情况。 ASP.NET MVC 使用 ViewContext 中的 ViewData

更新:

请尝试以下操作:

<% Html.RenderPartial("_Bar", Model.Bar ?? "Default" ); %>

Look at ASP.NET MVC source (HtmlHelper.cs -> RenderPartialInternal method -> line 258):

...

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

...

this is exactly your case. ASP.NET MVC uses the ViewData from your ViewContext

UPDATED:

Try this instead:

<% Html.RenderPartial("_Bar", Model.Bar ?? "Default" ); %>
云巢 2024-08-01 08:32:19

如果将 null 作为模型传递给 RenderPartial,那么它将查看原始模型,这就是错误显示 foo 的原因。

您需要确保 bar 初始化为空字符串而不是 null。

编辑: @Arnis,查看源代码。 它没有说谎。 您正在将 null 传递给 RenderPartial 的重载。您没有传递 Foo。 在内部,当您将 null Bar 传递给 RenderPartial 时,系统会使用页面 ViewContext(即 Foo)中的模型。

If you pass null as the model to RenderPartial, then it will look at the original model, which is why the error says foo.

You'll need to make sure that bar is initialized to be an empty string instead of null.

Edit: @Arnis, look at the source code. It doesn't lie. You are passing null to the overload of RenderPartial. You are not passing Foo. Internally, the system uses the Model from your page's ViewContext (which is Foo) when you pass a null Bar to RenderPartial.

千年*琉璃梦 2024-08-01 08:32:19

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

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