有没有理由为什么默认的模型绑定器不绑定到字段?

时间:2011-12-19 09:06:58

标签: asp.net-mvc-3 model-binding defaultmodelbinder

我正在使用ASP.NET MVC3,我想知道默认的模型绑定器绑定到公共属性,但不绑定到公共字段。

通常我只是使用属性定义模型类,但有时我会使用一些包含一些字段的预定义类。每次我必须调试并记住模型绑定器不喜欢字段。

问题:背后的原因是什么?

3 个答案:

答案 0 :(得分:2)

  

但有时我会使用一些预定义的类,其中包含一些字段

虽然我无法回答你关于默认模型绑定器仅适用于属性的确切原因的问题(我的猜测是它以这种方式尊重更好的封装并避免修改对象的内部状态,这是字段所代表的)我可以说您所谓的预定义类通常应该是视图模型。您应始终在控制器操作中使用视图模型。这些视图模型是专门定义的类,以满足给定视图的要求。

回到主要观点:字段应该只在给定的类中修改。不应该直接从外面访问它们。它们代表并保持着班级的内部状态。另一方面,属性应该是暴露给外部世界的。想象一下,在属性getter / setter中你有一些自定义逻辑。通过直接修改字段,此自定义逻辑将被破坏,并可能使对象进入不一致状态。

答案 1 :(得分:0)

可能忽略字段的原因是为了提高活页夹的性能。而不是搜索所有的字段和属性。 Model Binder仅搜索Properties。

虽然我认为Model Binder使用缓存来提高性能。

答案 2 :(得分:0)

DefaultModelBinder公开一个公共方法: DefaultModelBinder.BindModel,以及一些可用于覆盖的受保护方法。所有这些都列出了here

除了模型,这些方法仅涉及属性,而不是

等字段
  • GetModelProperties,
  • GetFilteredModelProperties,
  • GetPropertyValue,
  • OnXYZValidating,
  • OnXYZValidated,
  • OnXYZUpdating,
  • OnXYZUpdated,
  • GetXYZValue,

其中 XYZ 代表 Model, Property/ies, 或两者兼而有之,依此类推

正如您所看到的,这些名称中没有提及Fields。正如Darin所解释的那样,Binder不会容忍模型状态的直接变化。因此,方法中没有Field

而且,您可能希望看一下另一个重要的课程:ModelBindingContext。此类的实例将传递给BindModel,,然后传递给BindSimpleModel,BindComplexModel,,具体取决于模型类型(string, int, ...被认为是简单的,其他一切都很复杂)

因此,此上下文具有以下属性:

  • ModelXYZ和
  • PropertyXYZ。

换句话说,除非您不覆盖这些类并采取特殊操作,否则您无法引用ViewModel中的字段。

但是,再次,谨防打击框架,它总是更容易跟随它。

编辑: ModelMetadata类包含绑定模型所需的所有数据。但是,它的代码没有显示字段,字段名称等的符号。仅引用和访问属性。因此,即使您尝试继承并覆盖DefaultModelBinderModelBinderContext,您仍然无法访问fiellds,也无法访问其访问修饰符:public,private等。

希望这能解释大部分内容。