Sep 23, 2014

jQuery Unobtrusive client side form validation for ASP.NET MVC



Here at VeriTech we are using a modified version of Microsoft's jQuery Unobtrusive Validation, a support library for jQuery and jQuery Validate Plugin which is shipped with ASP.NET MVC since it's third release. It enhances client side validation, by using unobtrusive data-* validation attributes instead of generated code, like in previous versions. Thus, it is easily expandable and doesn't pollute your code.

We also maintain the BForms open source framework, making it the perfect platform to implement and publish the improvements that we added to the way in which validation works. Here I am going to list some of those changes and also explain the reasons behind them.
Even if you use client side validation you must validate your data on the server as well, by checking the ModelState.IsValid property. Also you should call the ValidationMessageFor HTML helper responsible for displaying the validation error messages from your ModelState. Sadly, this implies that you are going to redraw the form, adding an unnecessary overhead. That's why we made some small improvements to the flow of validating a form. First of all, we are using a modified version of the showErrors method from the jQuery validation plugin. We added a second boolean parameter which denotes if the viewport should scroll to the first form error, improving the user experience.
Another thing that we added was an extension method for the ModelStateDictionary class, which gathers all the model errors in an easy to use way.
 public virtual BsJsonResult GetJsonErrorResult()
        {
            return new BsJsonResult(
                new Dictionary { { "Errors", this.ModelState.GetErrors() } },
                BsResponseStatus.ValidationError);
        }
By using all the methods above and an overload of jQuery's ajax method, which includes some new callback methods, including one for server validation errors, we managed to give the users a seamless experience, without needing to replace the whole form to render the errors.
$.bforms.ajax({
                url: ajaxUrl,
                data: submitData,                              
                validationError: function(response){
                    var validator = $('.validated-form').validate();
                    validator.showErrors(response.Errors, true);           
                }               
            });
On that note, one of the most asked questions that I heard on the subject of unobtrusive validation is how are you supposed to handle new HTML added to your page. I found that the best way is to remove the data values added to the form, named "validator" and "unobtrusiveValidation" and calling the jQuery.validator.unobtrusive.parse method on the new content.
var $form = $('.validated-form');

$form.removeData('validator');
$form.removeData('unobtrusiveValidation');

$.validator.unobtrusive.parse($form);
Another thing that you are probably going to need at some time is some custom validation rules. There are two steps that you must complete to be able to do that. First, you have to create a new validation attribute, which inherits the the ValidationAttribute class and the IClientValidatable interface. After that you should call the jQuery.validator.unobtrusive.adapters.add method, which has the following parameters:
  • adapterName : The name of the adapter to be added. This matches the name used in the data-val-nnnn HTML attribute (where nnnn is the adapter name)
  • params:  An array of parameter names (strings) that will be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and mmmm is the parameter name)
  • fn : The function to call, which adapts the values from the HTML attributes into jQuery Validate rules and/or messages.
Don't forget to parse your form again to be sure that the new validation rules are added.
As you can see, you can manually add the data-val-nnnnn HTML attributes to your form elements without using a validation attribute, but then you are not going to be able to use the server side validation methods.

This is the way in which you can implement a custom rule for mandatory checkboxes (for example a Terms and Conditions agreement) :
//server side code using validation attributes
public class BsMandatoryAttribute : ValidationAttribute, IClientValidatable
{
    /// 
    /// Returns true if the object is of type bool and it's set to true
    /// 
    public override bool IsValid(object value)
    {
        //handle only bool? and bool

        if (value.GetType() == typeof(Nullable))
        {
            return ((bool?)value).Value;
        }

        if (value.GetType() == typeof(bool))
        {
            return (bool)value;
        }

        throw new ArgumentException("The object must be of type bool or nullable bool", "value");
    }

    public IEnumerable GetClientValidationRules(ModelMetadata metadata,
        ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "mandatory"
        };
    }
}
}
//client side validation methods
jQuery.validator.addMethod('mandatory', function (value, elem) {
        var $elem = $(elem);
        if ($elem.prop('type') == 'checkbox') {
            if (!$elem.prop('checked')) {
                return false;
            }
        }
        return true;
    });

jQuery.validator.unobtrusive.adapters.addBool('mandatory');

Another improvement that we added to the validator is the way in which validation errors are displayed. By default a label is added after your input which contains the raw error message. We replaced the label with a span containing a Bootstrap Warning Glyphicon. We also used the Bootstrap Tooltip plugin, so that you can see the validation by hovering over the exclamation mark, as you can see below:

For a live demo of a form validated using our modified version of Microsoft’s Unobtrusive validation you can check the  BForms Login Demo Page

Sep 5, 2014

Architecting an automatic updates system for windows services



We are working on a control and monitoring system for on-premises & cloud hosted servers and .NET applications. The monitoring is done by installing a windows service on all the virtual machines that are part of the system. The windows service’s job is to run (and keep open) a console app that collects data from the local machine and sends it to the monitor web service. After deploying the windows service to a dozen machines we realized that updating the collector component involves a lot of time and effort. So we've decided that we need an automated process that will detect when a new version of the collector component has been committed on Git, package the new version and apply it on all the servers.

Our automatic updates system is composed of a TeamCity server and a WebAPI service that collects the data, hosts the update packages and acts as a proxy between the TeamCity server and our windows services. We don’t want direct communication between TeamCity and the windows services since it would scale poorly (we can have multiple WebAPI services to distribute packages when we need to scale) and direct communication between the windows service host and TeamCity might not be wanted/possible.

TeamCity will detect changes in the Git repository of the collector component, pull the changes locally, build the collector project, increment the assembly version if the automated tests have passed, use MsBuild to build the project and archive the artifacts in a zip package. The package, containing the current version number in its name, gets deployed to the WebAPI service that stores it in its local storage.

Getting the update package from TeamCity to the update service can be done in several ways. We can configure TeamCity to deploy the WebAPI service along with the ZIP package via IIS Web deploy, but that would mean that every time a new update shows up the WebAPI service will have to be re-deployed and restarted. Another way to achieve this is to make the WebAPI service check the TeamCity API when the windows service asks it for updates. This is probably the best approach (taking development effort into account), and the downsides can be overcome by making the WebAPI service cache the results for a certain amount of time and only download a new update on the first request. Another approach would be to expose the updates folder as a network drive and XCopy the packages to it, but this requires setting up the TeamCity account to have write access to that folder.

There are several viable options for distributing the update package from the WebAPI service to the various windows services. The WebAPI can either push notifications to the windows service (using SignalR or Redis pub/sub), or the windows services can check for updates with the WebAPI service at some set interval. We’ve chosen to have the windows service poll the WebAPI for updates since it’s easier to implement and it’s not critical for us to update the collector component exactly at the moment a new version is available. If, however, we’ll need to make sure the collector is always up to date, the WebAPI service (which not only acts as an update agent, but also collects all the data sent from the collector) can check the collector’s version on each call it receives, and if a new one is present, tell the collector to signal the windows service that an update is needed.
The window service, once it downloads an update, waits for the collector console to finish the running job and shuts it down, unzips the package and overwrites all the files it contains, then starts the new version of the collector.

Since we’re distributing executables to many mission-critical machines, security is a big issue. Assuming the TeamCity server is secure from external attacks, the problem then lies with the updater service. If a WebAPI update service is compromised, then any machines requesting updates from it will be too. In order to mitigate this, the executables delivered by TeamCity need to be signed with a certificate that enables strong encryption. The windows service will then have to verify that the collector executable is signed before launching it.


We're interested to hear your thoughts on our design, improvements are always welcome. 

Sep 2, 2014

RequireJS.NET - open source project by VeriTech



Open source is not just for hobbyists, it is used successfully in some of the largest corporations on the planet. Most of the devices we use daily are in one way or another powered by open source. Since we also use open source software to great effect, it is our desire to give back to the community.

RequireJS.NET version 2.0 brings asynchronous JavaScript loading and flexible js bundling configuration to ASP.NET MVC. You can now have all the benefits of RequireJS and more in a way that is easy to use and fully integrated with .NET:
  • dependencies declaration and module path configuration using JSON or XML 
  • JavaScript file structure integrated with the MVC structure (js code-behind for each Razor view) 
  • bundling and minification with RequireJS.NET Compressor and MsBuild 
  • internationalization support for JavaScript resources with ResxToJs
Get started with RequireJS.NET: introductionsetup tutorial, bundling and compression, i18n support.

If you have suggestion or any kind of feedback regarding this project please submit an issue on GitHub.