KnockoutJS Unobtrusive Validation with ASP.NET MVC

Knockout JSASP.NET MVC has a really nice capability of generating client-side validation code based on the data annotations on your model. It can either generate a JavaScript code with the rules or generate data attributes on the input elements (unobtrusive). By using the second approach jQuery can read these data attributes (by the unobtrusive validation plugin) and automatically wire the validation logic up on the client. All this works great if you have a completely standard application – a user enters some input data and sends it to the server. However, if your application also requires some client-side logic along, you may consider KnockoutJS. The basic functionality of KnockoutJS, however, is not enough when input from the user is required. Fortunately, there is a plugin, which adds validation capabilities to KnockoutJS. It provides a set of rules like min, max, equals, etc., which we can use out of the box. Now the issue is how to make the data attributes, generated by ASP.NET MVC, and KnockoutJS validation play together. As I couldn’t find anything out of the box, I decided to create my own plugin.

How does KnockoutJS validation work?

Knockout validation uses the so called extenders to inject validation logic. See the following example

This extenders adds additional method to the observable, f.x. isValid(), which we can use to check its state. We can also validate a group of observables (or the entire ViewModel). These extenders, however, must be attached to the ViewModel properties before ko.applyBindings is called. So our goal is to read the data attributes, generated by ASP.NET MVC, and translate them into validation extenders.

The problems

The biggest problem is that we have to parse the data-bind attributes ourselves in order to determine which properties of the ViewModel we have to look at. Though, it does not sound that scary, it requires some logic behind. A good source of inspiration is the source code of KnockoutJS 🙂 Moreover, we have to define which bindings support validation.

The plugin

From the built-in bindings, I use only value and checked. However, I have taken into consideration that users can write their custom bindings, so I have enabled them to use their custom bindings for validation too.

  • ko.validation.unobtrusive.getAllowedBindings() – returns a list of all bindings, which are checked
  • ko.validation.unobtrusive.addAllowedBinding(name) – adds a new binding to the list
  • ko.validation.unobtrusive.removeAllowedBinding(name) – removes a binding from the list
Another point of extensibility, is the translation of rules. If you happen to write your custom validation rule for KnockoutJS, you can use it with the plugin too. All you need to do is create an implementation of the following interface:
  • getBindingString(htmlElement) – return the whole binding string from a HTML element. By default it reads the data-bind attribute
  • getRules(viewModel, htmlElement) – return an validation object according to Knockout Validation, which is set then via an extender
In order to replace the default ruleProvider, you have to call ko.validation.unobtrusive.setRuleProvider.
Finally, you need a way to trigger the actual validation. The first version works the following way: there is a custom binding, called validatesubmit, which you can set to the button you use for submission and pass it either the entire ViewModel of just a portion of it, which you want to validate.

Limitations

  • Currently the parsing of the data-bind string does not work pretty well. It supports only chains of properties (f.x., my.cool.property). However, it does not support with regions.

Conclusion

I have published the plugin in GitHub, so you can check it out. It is published under MIT license. Although, it does not yet look like a complete plugin, it does work pretty well. I plan to add some demos in the GitHub repository so that you can see it in action. Meanwhile, you are very welcome to do a fork or leave your a comment (here or in GitHub). Enjoy! 🙂