ASP.NET MVC3绑定到子类

8

我有一个类型为Question的超类,它有多个子类(例如MultipleChoiceQuestionTextQuestion)。每个子类都有自己的编辑模板(例如~/Shared/EditorTemplates/MultipleChoiceQuestion.cshtml)。

我想要做的是创建一个Question对象列表:

class Questionnaire {
    List<Question> Questions;
}

这将真正包含子类的实例:

Questions.Add(new MultipleChoiceQuestion());
Questions.Add(new TextQuestion());

然后我将问卷传递给View,在那里我调用:

@Html.EditorFor(m => m.Questions)

视图成功地为特定子类 Question 模型渲染了正确的编辑器模板。

问题在于,当表单提交时,我的 Questionnaire 模型(包含类型为 Question 的列表)仅包含 Question 的实例,而不包括子类的实例。此外, Question 属性的实例均为空。

作为测试,我传入了一个类型为 MultipleChoiceQuestion 的列表,它可以正常工作:

class Questionnaire {
    List<MultipleChoiceQuestion> Questions;
}

有没有办法让HttpPost Action返回我的模型,并使用表单数据实例化其中的子类?
谢谢。

这应该真正提交给ASP.NET MVC团队作为一个功能建议。我相信他们检查当前模型对象的GetType()并基于此获取模板不会太难 - 这样做可能会解决问题 =) - Tomas Aschan
Tomas,我认为这不是问题所在。模型有一个指定的类型,而绑定器正在从表单中的数据构建该类型的实例。相反,绑定器需要能够从表单中识别出所需的子类;因此需要使用自定义绑定器。 - Steve Morgan
你能发布MultipleChoiceQuestion.cshtml文件或其中的一部分吗?我知道以前复选框没有正确返回值的问题。这可能是问题的一部分吗? - Ed Charbeneau
1个回答

2

我认为你遇到了DefaultModelBinder的限制。要解决这个问题,你需要使用自定义模型绑定器。

你可能会发现这篇文章是一个有用的指南;它讨论了这个特定的问题。


这篇文章是上面链接文章的更新版本。虽然这篇文章没有解决我的问题,但它让我找到了一个解决方法。通过在视图中传递子类的类型,我能够在自定义模型构建器中检索它,并使用反射创建子类的实例。 - user853894

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