MVC HTML helpers and templates allow to factor out complex display logic into reusable, interoperable components. However, unlike standard asp.net controls, they lack the capability to recompose automatically the user input to fit the
view model. For instance, you can easily write an HTML helper to display a date with three dropdowns respectively for the year, month and day values, but after the user has edited them the standard model binder is not able to recompose this three input
fields into the original datetime model property.
Generally, an html helper may transform the data in a view model in a complex way when displaying it, but after the view is rendered the information about these transformations is lost! Thus, when the page is posted back
filled with the user input the model binder lacks the information on how to apply the reverse transformations. In the date example, nothing in the posted data says to the binder how to merge the year, month and data parameter into the original date. One can
modify the view model to adapt it to the way data are displayed in the view. For instance, in the example of the date, a programmer might decide to substitute the DateTime property with three integer properties. However, this would break
the separation of concerns between the view model that is supposed to specify what to display and the view that is supposed to specify how to display it.
One can inform the binding engine about the inverse transformation by defining a custom binder for the involved data type but then it will be used always with that data type, thus forcing all instances of a data type to be represented
in a similar way: sincerely this appears to be more a patch than an elegant solution. The right place where to specify how to recompose the original data type is the same HTML helper or template that defines how
to display the data type. This way programmers can design a view with the maximum freedom without caring about how to recompose back the view model.
The MVC Controls toolkit core offers tools to solve the above problems. Specifically, it supports the interface IDisplayModel that allows the definition of transformation to be applied to specific properties in the view model hierarchy
together with their inverse transformations.
Implementations of the IDisplayModel interface are called a transformation handlers and are invoked by HTML helpers. Each transformation handler defines a transformation of
a sub-model of the view model into another data structure that can be either rendered directly by its invoking HTML helper or used as a view model of a partial view.
When the HTML helper associated with a transformation handler is invoked it do the following:
- It applies a model transformation by calling its associated transformation handler.
- It renders information on which transformation handler the model binder need to invoke for transforming back the newly generated data structure into the original sub-model.
- Either renders directly the newly generated data structure or renders it by using templates.
Transformation handlers can be combined to yeld more complex transformations, and a view can use several transformations handlers.
The IUpdateModel interface works in a similar way but it allow parts of the view model at any depth to be used to define a new data structure to be passed to a Partial View(or to be transformed again). When the View is posted back, the core functions of MVC
Controls toolkit are able to recompose back the data into the original model. All heavy work needed to achieve this result is performed by the core of MVC Controls toolkit: the implementation of IUpdateModel is straightforward, and often actually
trivial. When the View is posted back the original model is updated in a custom way specified in the IUpdateModel implementations. Thanks to the IUpdateModel interface collection properties in the view model can be rendered in edit mode in
such a way that elements can be added or deleted without modifying either the View Model or the Controller: each item modifies the original collection by adding itself, so new elements are automatically added and deleted elements simply loose their opportunity
to be added.
The use of Transformations that are well defined mathematically enables the use of well known results and theorems of combinatorics in the design of complex controls. Such results can be used not only to prove formally the correctness of algorithms
but also to discover new algorithms, as in the case of the