我正在构建一个页面来编辑各种产品类型。每种产品类型都有一个继承自ProductVM的视图模型(TentProductVM,BootProductVM)。我的MVC2视图检查模型类型并根据需要添加字段。例如,如果模型是BootProductVM类型,我调用Html.TextBoxFor为引导的脚尺寸添加一个字段。页面显示正常。
问题在于帖子。我已经声明了一个函数(在VB中),如下所示:
<HttpPost()>Function Edit(byval prod as ProductVM) As ActionResult
当然,此函数仅接收来自基类ProductVM的表单数据。因此,我为每种产品类型添加了一个函数:
<HttpPost()>Function EditTent(byval prod as TentProductVM) As ActionResult
<HttpPost()>Function EditBoot(byval prod as BootProductVM) As ActionResult
并将View指向适当的帖子功能:
Using Html.BeginForm("Edit" & Model.ObjectTypeName, "Catalog")
但是,当调用EditTent或EditBoot时,prod参数仅包含基类中的数据。子类视图模型中声明的所有字段都保留默认值。
我做错了什么?还是有更好的方法? (显而易见的解决方案是多个页面,但由于ProductVM有许多相对于子类的字段,我宁愿不这样做。)
经过多次实验,我决定不使用这种方法。首先,如果不使用FormCollection类型的Action参数,我无法使其工作。其次,如果我使用局部视图,我丢弃的显而易见的解决方案很有吸引力。部分视图具有与基类(ProductVM)关联的所有字段,在常规视图中仅保留与派生类(TentProductVM,BootProductVM)关联的字段。
感觉就像我在与MVC自动魔法战斗,这绝不是正确的方法。
答案 0 :(得分:1)
要记住关于MVC的事情是它基于“约定优于配置”的思维模式。因此,如果您将强类型类类实例传递给action方法,则它希望将其命名为“model”。
尝试将声明更改为:
<HttpPost()> Function EditTent(byval model as TentProductVM) As ActionResult
<HttpPost()> Function EditBoot(byval model as BootProductVM) As ActionResult
另一个(不太理想)选项是期望在您的操作方法中使用FormCollection对象。
<HttpPost()> Function EditTent(byval form as FormCollection) as ActionResult
<强>更新强>
只是更新以包含下面的一些讨论点...为了将强类型对象发布到控制器操作方法,类型需要匹配。
假设您的控制器的操作方法如下所示:
<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>" %>