3

我有以下 ViewModels :

public class MyViewModel
{
  public BaseViewModel mySubViewModel;
}

public class ChildViewModel: BaseViewModel
{}

然后我创建了一个 MyViewModel 模型,它包含一个 ChildViewModel 类型的属性。在视图中,它显示得很好。

然后我点击保存按钮以提交对我的模型的更改并调用以下控制器:

    [HttpPost]
    public ActionResult Edit(MyViewModel model)
    {
        return null;
    }

令我惊讶的是,属性 mySubViewModel 现在是 BaseViewModel 而不是 ChildViewModel 类型!我不知道这里发生了什么。我究竟做错了什么 ?

4

1 回答 1

7

令我惊讶的是,属性 mySubViewModel 现在是 BaseViewModel 而不是 ChildViewModel 类型!我不知道这里发生了什么。我究竟做错了什么 ?

你不应该对此感到惊讶。你没有做错什么。这是设计使然。默认模型绑定器看到您的控制器操作正在接受一个MyViewModel参数,并试图将 POST 请求的内容绑定到它。默认模型绑定器绝对无法知道您可能已经编写了一些派生类(例如ChildViewModel在您的情况下)并且您希望在此处实例化这些派生类。您已将这个具体的视图模型实例从 GET 操作传递到视图这一事实对 POST 操作没有影响。根据 HTTP 和默认模型绑定器看到的内容来考虑它。例如,可以从一些完全不同的客户端而不是从表单提交中调用此 POST 操作。例如,可能是一个 iPhone 应用程序对 POST 操作执行 HTTP 请求。看,现在它很有意义。默认模型绑定器只能看到 POST 请求的有效负载和您指定为操作参数的类型。这就是他所做的 => 它实例化此类型并从 POST 有效负载数据绑定其属性。

因此,一种可能性是编写一个自定义模型绑定器,它将实例化您希望的视图模型的具体实例。我已经在this post. 在此示例中,我在表单中包含了一个隐藏字段,该字段将包含我们希望实例化的视图模型的具体类型,然后自定义模型绑定器只需使用此信息在运行时创建此类型。

于 2013-02-02T22:39:40.763 回答