Unobtrusive JavaScript Validation in ASP.NET

As promised, Paul Cociuba is back with part 9 of his series on ASP.NET – and this time he discusses improvements in validation controls in ASP.NET 4.5.

User input validation is an essential part of any data-driven web-application, and exposes a wide range of validation controls to help developers achieve this easily. The validation controls in have been around since version 2.0 of the product, but in this chapter I want to focus on the improvements brought on by WebForms 4.5 and on how the model definition of the Entity Framework classes and the Dynamic Data UX framework work together to generate the validation we need on the application with minimal development effort.

For your convenience, here is an annotated timeline of the video:

1:45 – I start by looking at the UpdateProduct method call in the ProductDetails.aspx code-behind. The first thing this method tries to do is to load the Product entity we are trying to update from the database so we can perform changes on it in memory. This is done by calling the Find() extension method on the Products property of the context object.

2:30 – should no product with the given ID be found (since it may have been deleted in the meantime), we need to modify the method to signal an error. This is done via the ModelState object that is exposed by the Page, and via a call to the AddModelError method of this object. This adds an error to the ModelState object that will later be used by the UI logic.

3:25 – we also need to modify the UpdateCategory method of the CategoryDetails.aspx page code-behind to return an error if the category we are trying to update is not found. When adding an error to the ModelState, an error key is to be provided along with the message to be displayed. This will allow the UI to look for certain errors and display them should validation errors occur.

4:20 – to display the validation errors on the CategoryDetails.aspx page, I will make use of the ValidationSummary control. This control exposes an attribute called ValidationGroup, which tells the control to only show errors coming from a certain group of controls. Each control in the group is also marked with the ValidationGroup attribute to indicate its belonging to a specific group of controls for validation purposes.

5:37 – a second ValidationSummary control is to be added to the same page, this time in the EditItemTemplate, as the previous control was added to the InsertItemTemplate. The ValidationGroup on this second control is called ‘Edit’ and this value is also set on all the data-entry controls in the EditItemTemplate via the ValidationGroup attribute.

6:06 – the same ValidationSummay controls are also to be added to the ProductDetails.aspx page, in the InsertItemTemplate and EditItemTemplate pages.

7:10 – when running the project after the modifications above, we can observe that the DynamicControl controls used in the FormView controls actually generate their own validation controls. Trying to create a new Product with no data filled in will generate several error messages from these controls, messages that will all be displayed on the ValidationSummary control.

Setting up a negative value for the price of the new product will generate a different error message that will be displayed on the ValidationSummary – indicating that the value is not within the expected range. This is because the Range property of the Product entity was decorated with the [Range] attribute to indicate acceptable ranges for values.

8:20 – the way in which validation works in using Dynamic Data is that the Dynamic Data field templates for insert and edit actually come with validation controls already added to the template markup. A look at the Text_Edit.ascx field template shows that it comes with three validation controls – of type RequiredFieldValidator, RegularExpressionValidator and DynamicValidator as well as the code behind to wire up the validation controls based on the model constraints.

9:35 – validation controls in Web Forms used to work by injecting JavaScript code into the source of the page to express the validation logic. The JavaScript was easily observable in the form of arrays at the bottom of the page in source-code. The new unobtrusive validation does away with the injection and an inspection of the source code of the page when adding a new category shows this clearly.

10:16 – inspection of the page source code with the browser tools from Internet Explorer shows that JQuery is loaded with the page. The validation from WebForms makes use of JQuery to select the controls that are in need of validation and to express the validation logic.

10:50 – under the covers, each validation control markup emitted on the page is decorated with data- (read: data dash) attributes. The three spans that correspond to the validation controls of the Text_Edit.ascx template all have such attributes in the markup. Attributes such as data-val-controlToValidate, data-val-errorMessage are then used by JQuery to select the correct controls for validation and perform the validation logic on these controls.

12:20 – to complete the sample I introduce a new validation control that is shipped with 4.5: the ModelErrorMessage control. This control will be added after the FormView control markup on the category and product details pages. The model displays ModelState error messages, in the case of the sample app, error messages with the ErrorNotFound key, added via the AddModelError method. This is done by specifying which key to display messages for via the ModelStateKey attribute.

14:20 – when running the sample again, we will select the same product in two different browser tabs. One tab will be used to start editing the product, while the other will be used to delete the product.

15:18 – to better understand execution, we set a breakpoint on the UpdateProduct method call to allow for step by step execution. Trying to find the product fails (since it was already deleted) and hence leads to a call to AddModelError. When the page is displayed the ModelErrorMessage control also displays the error message (alongside the ValidationSummary control).

Adding a value of -45 units for the product units in stock will cause the ValidationSummary to display another error message, while the ‘product not found’ error message is still displayed by the ModelErrorMessage control. This clearly shows that some validation (like the range) sis done client side, while other validation is done server side.

[Post recording note:] allows for both client side validation – where the JavaScript running on the page will validate input, as well as server side validation. Each validation control that has client side validation will also implement server side validation, since JavaScript execution in the browser can be disabled by the end user to bypass validation on the client.

16:55 – finally, the unobtrusive behavior of validation in 4.5 is brought on by the presence of the ValidationSettings:UnobtrusiveValidationMode attribute in the application key settings in the web.config. This attribute can be turned off or removed to disable this type of validation if needed.

The next chapter of the series will look at how sorting can be implemented in the application and some CSS enhancements we can bring to the web-interface.


Original content from Paul Cociuba; posted by MSPFE editor Arvind Shyamsundar

Comments (0)