Binders
In this lesson, we will learn how to use Binders for form filling.
We'll cover the following
During the action methods, parameters-filling stage data extracted from headers, routes, query strings, and form fields is not processed by a single software module but by several objects called binders. Each binder is specialized for a particular .NET type, or for a whole category of C# types. More specifically, there are:
-
Model binders that are specific for each .NET basic type (string,
Guid
, int, long, decimal, float). -
A binder that handles all complex types, that is, a binder for the types with several properties.
-
A binder specific for any
IEnumerable
. -
A binder that handles all
Dictionary<S, T>
.
The model binding process is recursive and starts from the type of the parameter. If the type is a simple type, the binder immediately fills the parameter. Otherwise it recursively invokes the binders for all parts that compose the type, that might be properties, all elements of a collection, all keys, and all values of a dictionary.
Whenever recursion goes down, a suffix is added to the name of the lookup source. For example, the Address
property of a Person
type would add an “Address” suffix to current lookup name. Similarly, the .Town
suffix is added to the Town
property of the address, which leads to a total prefix of Address.Town
.
Two initial prefixes are tried, the empty string and the parameter name, so if the parameter name is customer
the value for the Town
property are searched in sources with the names customer.Address.Town
and Address.Town
. All name matches are case-insensitive.
In case of any IEnumerable
, each time the algorithm goes down the ith element the [i]
suffix is added, but in this case no period (.
) is added to separate [i]
from the remainder of the lookup name.
In the remainder of the section, we will analyze how the three binders for complex types, collections, and dictionaries work.
Binding complex types
The binder that handles complex types attempts to fill all public properties that have a setter. No attempt is made to fill fields, only properties are processed.
If the complex type of the action method parameter is the same as the model used by the view containing the form that submitted the data, then all field values are automatically given the right names for the whole model binding algorithm to match properly all properties.
Thus, for instance, the name that is automatically assigned to the input field used to render the Town
property nested into an Address
property of a Person
object will be Address.Town
. This name is the same Address.Town
lookup name used to match the same Town
property of a Person
parameter in the action method targeted by the form submit.
However, if we use different models, a match can be forced either by overriding the automatically generated input field name with an explicitly provided name attribute or by overriding the lookup name of the Town
property with a ModelBinderAttribute
, as shown below:
Get hands-on with 1400+ tech skills courses.