Asp.net mvc 使用子类的MVC2 Post

Asp.net mvc 使用子类的MVC2 Post,asp.net-mvc,asp.net-mvc-2,Asp.net Mvc,Asp.net Mvc 2,我正在构建一个页面来编辑各种产品类型。每个产品类型都有一个从ProductVM继承的视图模型(TentProductVM、BootProductVM)。我的MVC2视图检查模型类型,并根据需要添加字段。例如,如果模型是BootProductVM类型,我将调用Html.TextBoxFor为靴子的脚大小添加一个字段。页面显示良好 问题在于邮政。我声明了一个函数(在VB中),如下所示: <HttpPost()>Function Edit(byval prod as ProductVM)

我正在构建一个页面来编辑各种产品类型。每个产品类型都有一个从ProductVM继承的视图模型(TentProductVM、BootProductVM)。我的MVC2视图检查模型类型,并根据需要添加字段。例如,如果模型是BootProductVM类型,我将调用Html.TextBoxFor为靴子的脚大小添加一个字段。页面显示良好

问题在于邮政。我声明了一个函数(在VB中),如下所示:

<HttpPost()>Function Edit(byval prod as ProductVM) As ActionResult
但是,当调用EditTent或EditBoot时,prod参数仅包含基类中的数据。子类视图模型中声明的所有字段都保留默认值

我做错了什么?还是有更好的方法?(显而易见的解决方案是多页,但是,由于ProductVM有许多与子类相关的字段,所以我不希望这样。)


经过多次试验,我决定不使用这种方法。首先,如果不使用FormCollection类型的操作参数,我就无法让它工作。第二,如果我使用局部视图,我放弃的显而易见的解决方案很有吸引力。部分视图具有与基类(ProductVM)关联的所有字段,在常规视图中只保留与派生类(TentProductVM、BootProductVM)关联的字段


感觉就像我在与MVC auto magic抗争,这从来都不是正确的方法。

关于MVC,需要记住的是,它是基于“约定优先于配置”的心态。因此,如果要将强类型类实例传递给动作方法,它希望将其命名为“model”

尝试将声明更改为如下所示:

<HttpPost()> Function EditTent(byval model as TentProductVM) As ActionResult
<HttpPost()> Function EditBoot(byval model as BootProductVM) As ActionResult
Function EditTent(byval模型作为TentProductVM)作为ActionResult
函数EditBoot(byval模型为BootProductVM)作为ActionResult
另一个(不太理想的)选项是在action方法中使用FormCollection对象

<HttpPost()> Function EditTent(byval form as FormCollection) as ActionResult
Function EditTent(byval表单作为FormCollection)作为ActionResult
更新

只是更新以包含下面的一些讨论点。。。为了将强类型对象发布到控制器操作方法,类型需要匹配

假设控制器的操作方法如下所示:

<HttpPost()> Function EditTent(byval model as ProductVM) As ActionResult
Function EditTent(byval模型为ProductVM)作为ActionResult
应相应地键入您的视图:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Your.Namespace.ProductVM>" %>


令我惊讶的是,我将参数名称更改为“model”,并将其设置为null!问题可能是我的视图继承了System.Web.Mvc.ViewPage(MyNamespace.ProductVM的),但我的post函数参数是BootProductVM的子类?(如果编辑各种产品类型要共享一页,这当然是不可避免的。)这样就可以了。如果您想要有一个使用这样的通用ViewModel的共享视图,那么您必须在action方法中接受“ProductVM”。然后将其映射到控制器方法中的实际数据模型。你也可以创建一个定制的ModelBinder,但我认为第一个选项是最简单的。啊,我如何“将它映射到你的实际数据模型”?如果在我的操作中接受ProductVM类型的参数,MVC(或我)如何将子类字段映射到我的参数?好吧,假设ProductVM只是一个ViewModel,并且您有一个实体类,用于将信息持久化到数据存储,您可以手工编写映射代码(例如,-entity.Property1=model.Property1…)或使用类似的方法帮助您实现自动化。
<HttpPost()> Function EditTent(byval model as ProductVM) As ActionResult
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Your.Namespace.ProductVM>" %>