Model Binders in Web Forms vNext
Despite claims of its death, ASP.NET Web Forms is still a very popular framework and Microsoft is continuing to invest heavily in it. Web Forms vNext offers significant improvements in several areas including strongly typed, two-way data binding.
Strongly typed data controls use the ModelType attribute. The Eval-based data binding is replaced with directly referring the property using “<%# Item.Property %>” or for child controls, “<%# BindItem.Property%>”. IntelliSense is fully supported within those data-binding expressions once the aforementioned ModelType attribute is set. This should also offer better compile time error checking and performance. Unlike the previous binding logic, you can use complex types and drill down as far as you need to.
A form of two-way data binding for Web Forms was originally introduced in .NET 2.0. However it was never very popular. (During the presentation at MIX 2011 non-one raised their hand when the presenter, Damian Edwards, asked who was currently using it.) While the demos for it looked nice, Microsoft acknowledges that it turned out to be rather clumsy.
In the new model the select, insert, update, and delete methods are exposed right on the control, there is no longer a need to use the external data source. Inside these strongly typed methods you can encapsulate some of you data access logic.
I say some because the control is allowed to participate in data access. For example, if you are using a data grid with paging turned on the select method needs to follow one of two patterns:
- Return an IQuerable so that the control can call Skip and Take
- Return an IEnumerable and expose parameters for startRowIndex, maximumRowIndex, and totalRows.
This form of data binding works particularly well with ORM frameworks such as Entity Framework and nHibernate. Even the support IQuerable is optional, though it will work better if used.
ModelState is a concept that comes from ASP.NET MVC. It uses the same validation attributes from System.ComponentModel.DataAnnotations that MVC, Entity Framework, and WCF RIA Services use. When an insert, update, or delete method you would use the ModelState object to get and set validation information. In the view, the ValidationSummary class now supports showing model state errors.
Another interesting change is the use of attributes in the binding functions. In the demo PRESENTOR showed using attributes on the model binding function to read values from an alternate source such as a query string. At runtime the control will see these attributes and ensure the value is fetched from the correct query string, cookie, view-state, session, or control.
IEnumerable<Customer> SelectCustomers( [QueryString] int? minAge)
The value binding provider needed to make this work is extensible. Based on work in MVC Futures, you can easily write your own attribute with custom semantics. Just like MVC, you can also write your own model binding provider.
Two variants of the model binding were shown for the insert method:
- void InsertCustomer()
- void InsertCustomer(Customer newRecord)
The first version is called “explicit binding” and requires the developer to manually create the object and trigger model binding on it. The second version does all that for you, passing in a new object that was automatically populated from the binding expressions. Unless you need full control of when binding occurs, the second method should be used.