默认模型绑定器不绑定到字段是否有原因?

发布于 2024-12-21 16:01:30 字数 152 浏览 2 评论 0原文

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

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

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

I'm using ASP.NET MVC3 and i'm wondering that the default modelbinder binds to public properties but not to public fields.

Normally i just define the model classes with properties but sometimes i use some predefined classes which contains some fields. And everytime i have to debug and remember that the modelbinder just don't like fields.

The question: Whats the reason behind it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

盗梦空间 2024-12-28 16:01:30

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

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

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

but sometimes i use some predefined classes which contains some fields

While I cannot answer your question about the exact reason why the default model binder works only with properties (my guess is that it respects better encapsulation this way and avoids modifying internal state of the object which is what fields represent) I can say that what you call predefined classes should normally be view models. You should always use view models to and from your controller actions. Those view models are classes that are specifically defined to meet the requirements of the given view.

So back to the main point: fields are supposed to be modified only from within the given class. They should not be accessed directly from the outside. They represent and hold internal state of the class. Properties on the other hand is what should be exposed to the outside world. Imagine that in the property getter/setter you had some custom logic. By modifying directly the field this custom logic would be broken and potentially bring the object into an inconsistent state.

网名女生简单气质 2024-12-28 16:01:30

也许忽略字段的原因是为了提高绑定器的性能。而不是搜索所有字段和属性。 Model Binder 仅搜索属性。

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

Maybe the reason for ignoring fields is to increase performance of the binder. Instead of searching all the Fields and properties. The Model Binder search for Properties only.

Though I think the Model Binder use cache to improve performance.

掩饰不了的爱 2024-12-28 16:01:30

DefaultModelBinder公开了一个公共方法:
DefaultModelBinder.BindModel,以及许多可用于重写的受保护方法。所有这些都列出了此处

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

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

其中 XYZ 代表模型,属性, 或两者,等等。

正如您所看到的,这些名称中没有提及任何 Fields。正如 Darin 所解释的,Binder 不容忍对 Model 状态的直接更改。因此,其方法中没有 Field

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

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

  • ModelXYZ 和
  • PropertyXYZ。

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

但再次强调,要小心与框架作对,遵循它总是更容易。

编辑: ModelMetadata 类保存绑定模型所需的所有数据。然而,它的代码没有显示字段、字段名称等的迹象。仅引用和访问属性。因此,即使您尝试继承并覆盖 DefaultModelBinderModelBinderContext,你仍然无法访问字段,不管它们的访问修饰符是什么:公共、私有等。

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

DefaultModelBinder exposes a public method:
DefaultModelBinder.BindModel, and a number of protected method available for overriding. All of them listed here.

Besides the model, these method refer to properties only, not fields, like

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

where XYZ stands for either Model, or Property/ies, or both, and so on.

As you can see there is no Fields mentioned with these names whatsoever. As Darin explained no direct changes to Model's state are tolerated by the Binder. Hence no Field in its methods.

And also, you may wish to take a look at another important class: ModelBindingContext. An instance of this class gets passed to the BindModel, and subsequently to BindSimpleModel, and BindComplexModel, depending on model type (string, int,... are considered simple, everything else is complex).

So, this context has the following properties:

  • ModelXYZ, and
  • PropertyXYZ.

In other words you have no means to reference the fields in your ViewModel unless you do not override these classes and undertake special actions to do so.

But again, beware of fighting the framework, its always easier to follow it instead.

EDIT: The ModelMetadata class holds all the data needed to bind the model. Its code however, shows no sign of fields, field names, etc. Only properties are referenced and accessed. So, even if you try to inherit and override DefaultModelBinder and ModelBinderContext, you still won't be able to access fiellds, nevermind what their access modifier is: public, private, etc.

Hope this explains most of it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文