0

几天前我发布了这个问题的背景..但答案还不完整,所以重新发布一个摘要。

我正在开发一个 MVC 3 Razor Web 应用程序,其中存储了多个对象类别的详细信息。(车辆、房屋、仪器等)。所有对象共享一些公共数据(标题、描述等)和一些特定于其所属类别的详细信息。Category 列表预计会增长,并且考虑到降低可维护性,我们希望重用相同的 Add Object 向导。该向导基于以下实现。

http://afana.me/post/create-wizard-in-aspnet-mvc-3.aspx

在多步骤向导过程中,最后一步允许用户输入特定类别的详细信息(车辆的型号、品牌、VIN 等)。视图页面绑定了“AssetView”Model,定义如下

public class AssetView
{
    [Required]      
    public string Title { get; set;  }

    [Required]
    public string Description { get; set;}

    public SpecificAsset AssetDetails { get; set; }
}

AssetDetails 属性将在运行时根据前一阶段选择的类别类型动态更改。视图看起来像这样

@model AssetView
....
<div class="wizard-step">
  ...
 </div>
<div class="wizard-step">
  ...
 </div>
<div class="wizard-step">
  @Html.EditorFor(model => model.AssetDetails)
 </div>

在控制器中,基于类别选择。我初始化assetdetails如下

_thisAsset.AssetDetails = new MotorAsset();

然后,我使用类型特定的编辑器模板覆盖视图。

向导工作正常,但在控制器的“保存”步骤中,“AssetDetails”属性没有值,并且显示为“SpecificAsset”类型,这是基本类型。我也无法将其转换为特定类型。但是 formsCollection 显示所有值,“AssetDetails”特定属性(如“Transmission”、“Make”)位于以“AssetDetails_”为前缀的表单集合中。

请记住,我需要在控制器保存步骤中处理 20 多种特定类别(电机、房屋等),我如何在没有某种 hack 的情况下做到这一点?

4

2 回答 2

0

如果您知道 AssetDetails 的类型,您可以这样做:

  1. 将 AssetView 作为参数传递给动作(绑定常用属性)
  2. 创建特定 AssetDetails 的新实例(例如 CarDetails)
  3. 使用 TryUpdateModel 的重载之一来绑定值。有一些重载可让您指定前缀,因此它应该始终有效
  4. 将此对象添加到 AssetView.SpecificAsset

您需要一些方法来了解具体类型。但我想你会有一个跟踪类型的变量,所以你以后可以正确保存它。如果你不这样做,它会很容易添加。请记住,它需要是 AssetView,因为 AssetDetails 没有被绑定。

如果您需要验证,那么您也可以尝试使用 TryValidateModel。

于 2011-02-01T06:15:28.193 回答
0

据我了解,模型的数量会增加,您希望为所有模型重用操作和视图。我看到的一种选择是制作自定义 ModelBinder。您将检查 FormCollection,然后创建一个特定的资产模型。

您的解决方案的问题是 SpecificAsset 没有属性,因此默认模型绑定器不会将任何字段绑定到它。

于 2011-02-01T07:04:37.247 回答