使用不同模型呈现强类型部分视图

3
我有两个视图: 1)注册 - 用于创建用户帐户的主要视图 2)类别 - 部分视图,用于在注册视图组合字段中没有该类别时动态添加类别。
当用户点击“添加类别”时,类别视图显示为 jQuery 对话框。此视图显示构成新类别所需的字段,如名称和描述。因此,它具有单独的模型。
在获取页面上,一切正常,但是在提交后,如果存在一些验证错误,则页面需要重新加载以提供用户提供的值进行更正,而不是抛出以下错误:
异常详细信息:System.InvalidOperationException:字典中传递的模型项的类型为'Delight.Models.User',但此字典需要类型为'Delight.Models.Category'的模型项。
我认为使用以下语句可能会导致此问题(因为它没有指定用于部分视图的模型对象):
@Html.Partial("CreateCat")

然而,使用以下重载也未能解决问题:
@Html.Partial("CreateCat", null, null)

在第二个参数(具有null值)之上,表示模型对象。

然而,出乎意料地,以下解决了我的问题:

@Html.Partial("CreateCat", new Category(), null)

为什么在这种情况下空对象可用,但null不可用?

是否有其他更好的方法来呈现具有不同模型类型的强类型部分视图。


我认为这并不是MVC模式应该使用的方式...也许你的部分视图应该被集成到你的页面中或者放在一个单独的页面上? - Jeremy Holovacs
@Jeremy,我没有其他选择。该类别是通过ajax添加的,我不想为用户打开新的浏览器窗口来完成此操作。实际上,它永远不需要任何后台数据。顺便问一下,关于MVC,这里有什么问题吗?MVC不应该让我们更好地控制如何构建不同的组件吗? - Varun K
因为如果您将一个空对象传递给视图,它会在您的代码中崩溃(除非您首先检查空模型)。调用Html.Partial("CreateCat")将传递父模型(Models.User)。使用新的Category()调用它,我想本质上就是控制器在返回一个空的、新的Category以创建时所做的操作。编辑:我可能对此理解不正确,因为我是MVC的新手,但这是我所理解的。 - Jack
2
听起来你的“添加类别”方法应该是一个ajax调用,而不是一个部分视图。你想要在DOM中改变的唯一事情就是向组合框添加另一个选项,对吧?你的jQuery post变量应该与你的CategoryAdd模型匹配,并返回一个JsonResult,描述任何你需要添加到DOM的下拉项信息,并使SELECT值可消耗。 - Jeremy Holovacs
@Jeremy 这正是我正在做的事情。我已经将类别分成了一个局部视图,以使代码更加清晰。这个局部视图只在完整页面加载时呈现(隐藏)。当用户点击添加链接(在类别组合框之前)时,它会出现为一个对话框。用户指定名称和描述,通过ajax进行发布,对话框消失,新的categoryId+名称被附加到原始组合框中。 - Varun K
这仍然不像应该是一个部分视图,特别是有模型的情况下。如果你想保持代码分离,你应该能够在一个部分非类型化视图中实现(在主页面表单之外,没有其他表单),而你的添加类别方法需要是完全不同的...它将不会有关联的视图,因为它将返回纯Json。 - Jeremy Holovacs
1个回答

3

除非你想使用父模型或没有模型,否则应始终传递适当的模型给部分视图。如果传递null,则是愚蠢的。如果您不想在部分视图中实例化模型,那么为什么您的部分视图会使用模型呢?在这种情况下,我认为new Category()是正确的选择。但是,我经常看到子模型被传递到部分视图中。

@Html.Partial("CreateCat", Model.Category)

需要做你正在做的事情似乎有些奇怪,但我不确定你如何使用部分视图。


我需要使用部分视图,因为该类别本身是一个单独的模型(虽然非常小),具有像字符串长度等验证器。正如我在评论中所说(请参见上文),虽然可以通过打开新的浏览器窗口来完成此操作(以避免使用部分视图),但我希望使用jQuery对话框和预加载的HTML使其具有流畅的用户体验。 - Varun K
Model.Category 对我来说看起来不错,但我认为我可以坚持我的解决方案,因为在完整页面加载期间类别视图始终为空。感谢您的答案。 - Varun K
我不同意“始终为部分视图传递适当的模型”的说法。例如,我的部分视图生成一个MemberID下拉列表,视图的模型肯定是“Members”。可以通过@model关键字在视图顶部声明模型。 - Cheung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接