-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Summary
MVC has a few different flavours of binding attributes and they each do different things, largely for legacy reasons - but they also overlap in some ways which leads a lot of confusion. We've tried to keep them orthogonal in the past, but they didn't start that way, so maybe we should stop trying?
Could we think about making them consistent and maybe deprecating some? Time horizon for this is long-term. I want to come up with a plan for the zoo of current stuff.
Existing Stuff
We have the following attributes:
[Modelbinder]
[Bind]
[BindProperty]
[FromBody]/[FromHeader]/[FromServices]/[FromRoute]/[FromQuery]/[FromForm]
[BindRequired]/[BindNever]/[BindingBehavior] // these are hidden away in the .ModelBinding namespace for some reason
We also have the following policies that these attributes can configure (see BindingInfo):
- Binding Source (where do we look for data)
IBindingSourceMetadata
- Model Name (what's the key-space)
IModelNameProvider
- Binder Type (specifies a model binder to use by-type)
IBinderTypeProviderMetadata
- Property Filters (Include)
IPropertyFilterProvider
- Request Predicate (filter by request type)
IRequestPredicateProvider
- Binding Behavior (never, required) - this is actually part of model metadata which is wierd -
BindingBehaviorAttribute
Here's a handy table:
Targets | Binding Source | Model Name | Binder Type | Property Filter | Request Filter | Binding Behavior | |
---|---|---|---|---|---|---|---|
[ModelBinder] | All | X | X | X | |||
[Bind] | Type, Parameter | X | X | ||||
[BindProperty] | Property | X | X | X | X | ||
[FromRoute] | Parameter, Property | X | X | ||||
[BindRequired] | All | X |
Some random thoughts
[ModelBinder]
, [Bind]
and the [BindRequired]
family all have their root in our legacy systems, but only [ModelBinder]
is truly compatible with MVC5. We cut exclude
support from [Bind]
and the [BindRequired]
attribute used to be called [HttpBindRequired]
. This makes me sad because it represents a missed opportunity 👎
The [FromXyz]
is new as of ASP.NET Core and is mostly intended to for APIs.
[BindProperty]
is a new feature that was added for Razor Pages. It's special trick is that it doesn't bind on GET requests by default IRequestPredicateProvider
[BindRequired]
and friends don't support any real customization of the model binding system. They are kinda separate.