默认模型绑定器不绑定到字段的原因是什么?



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

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

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

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

虽然我不能回答你的问题,为什么默认模型绑定器只与属性工作的确切原因(我的猜测是,它尊重更好的封装这种方式,避免修改对象的内部状态,这是什么字段表示),我可以说,你所说的预定义类通常应该是视图模型。你应该总是使用视图模型往返于你的控制器动作。那些视图模型是专门为满足给定视图的需求而定义的类。

回到要点:字段应该只能在给定的类中修改。它们不应该直接从外部访问。它们表示并保存类的内部状态。另一方面,属性是应该暴露给外界的东西。假设在属性getter/setter中有一些自定义逻辑。通过直接修改字段,这种自定义逻辑将被打破,并可能使对象进入不一致的状态。

可能忽略字段的原因是为了提高绑定器的性能。而不是搜索所有的字段和属性。模型绑定器只搜索属性。

虽然我认为模型绑定器使用缓存来提高性能

DefaultModelBinder公开了一个公共方法:DefaultModelBinder。BindModel,以及一些可用于重写的受保护方法。都列在这里。

除了模型之外,这些方法只引用属性,而不引用字段,如

  • GetModelProperties,
  • GetFilteredModelProperties,
  • GetPropertyValue,
  • OnXYZValidating,
  • OnXYZValidated,
  • OnXYZUpdating,
  • OnXYZUpdated,
  • GetXYZValue,

其中 XYZ 表示 Model, Property/ies, 或两者同时表示,以此类推。

正如您所看到的,这些名称中没有提到Fields。正如Darin解释的那样,Binder不允许直接更改Model的状态。因此在它的方法中没有Field

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

那么,这个上下文有以下属性:

  • ModelXYZ和
  • PropertyXYZ。

换句话说,你没有办法引用ViewModel中的字段,除非你不覆盖这些类并采取特殊的操作来这样做。

但是,要注意不要与框架作斗争,遵循它总是更容易。

EDIT: ModelMetadata类保存绑定模型所需的所有数据。但是,它的代码没有显示字段、字段名等符号。只有属性被引用和访问。所以,即使你尝试继承和覆盖DefaultModelBinder和ModelBinderContext,你仍然不能访问字段,不管它们的访问修饰符是什么:public, private,等等。

希望这能解释大部分。

相关内容

  • 没有找到相关文章

最新更新