4

通过 ASP.NET MVC 调用方法时,在以下情况下,我的 viewModel 参数永远不会为空吗?例如使用 URL “.../Home/Index”。

public ViewResult Index(HomeViewModel viewModel)
{
  // .. do stuff...viewModel is never null here when called within ASP.NET?
}

我以前从未在 ASP.NET MVC 中注意到这种行为,但 ViewModel(如果未提供)似乎正在实例化。

有人可以澄清这种行为。

4

3 回答 3

10

是的,即使请求中不存在可分配给视图模型的任何参数,您也将始终获得视图模型的实例。

为什么会发生这种情况?

作品是这样的DefaultModelBinder

  1. 创建视图模型的实例。

  2. 迭代模型中的属性并要求值提供者查找值并将找到的值设置为属性。

  3. 返回创建的实例。

如果您看到这些步骤,DefaultModelBinder它并不关心请求中是否有任何可以设置为模型实例的值,它只是提前开始并创建实例,然后填充属性。

这没什么意义吧?

模型绑定器检查请求是否包含与模型属性匹配的任何值然后创建实例会更复杂。

于 2012-07-24T16:59:19.303 回答
4

MVC 将尝试获取通过 POST/GET 发送的值并“自动”将它们绑定到模型的属性。这是由默认模型绑定器完成的。在大多数情况下,默认模型绑定器将完成您需要的所有操作。

您可以更深入地了解自定义模型绑定(并且可能会更深入地了解它),但可以查看 IModelBinder 接口——它包含一个名为 BindModel 的方法。在这种方法中,您几乎可以获取 ControllerContext.HttpContext.Request 中的任何内容并填写您的类属性(基本上与默认模型绑定器所做的相同)。使用自定义模型绑定器还有一些您需要跳过的障碍,但会让您了解绑定生命周期。

简短的回答:使用默认模型绑定器,它不会为空。

高温高压

于 2012-07-24T16:23:26.060 回答
0

当 action 方法参数是复杂类型时,DefaultModelBinder 类使用反射来获取公共属性集,然后绑定到每个公共属性。对于它使用的复杂类型,Activator.CreateInstance(typeToCreate);然后将使用 ValueProviders 来获取这些属性的值。请记住,模型绑定器不会锁定到特定的源,但它们可以从源的聚合中构建对象。

于 2012-07-24T16:41:45.470 回答