Skip to content

Consistency across binding attributes #4857

@rynowak

Description

@rynowak

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.

Metadata

Metadata

Assignees

Labels

Needs: DesignThis issue requires design work before implementating.area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesenhancementThis issue represents an ask for new feature or an enhancement to an existing one

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions