Binders

In this lesson, we will learn how to use Binders for form filling.

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.