Tuesday 26 May 2015

Custom Validations in ASP.NET MVC using DataAnnotations

In this article we will see how we can perform custom validations by using custom data annotations in ASP.NET MVC i.e. implementing custom validation attributes in ASP.NET MVC.

We have seen that using the data annotation technique we can perform following validations:
  • Required fields: RequiredAttribute
  • Restricting the length of user input: StringLengthAttribute
  • Regular expression based input constraints: RegularExpressionAttribute
Now what if we have requirements to perform custom validations. Would it be possible to perform custom validations using this DataAnnotation technique. In this article, we will be discussing how we can perform custom validations for Model properties by using data annotations i.e. implementing custom validation attributes.

Using the code
Now to understand the custom validations using data annotations, I will be continuing with the sample application from the previous article. so Let us take a quick look at what is there in the existing application.

Database
In this application we have a single table database. This table (called as Contacts) contain the information of a contact person.
Now in this table, All the fields are not-null i.e. they will be required from the user.
  • FirstName: varchar(50)
  • LastName: varchar(50)
  • Address: varchar(100)
  • PhoneNumber: varchar(15)
  • eMail: varchar(35)
  • Age: INT

Note: The age field has been added for this article to demonstrate a custom validation rule.

Models, Views and Controllers
To perform data access we are using entity framework database first approach. So our contact entity looks like:


The application contains views to perform CRUD operation on the model. and the controller for the performing these operations looks like:

public class ContactController : Controller
{
    private SampleDbEntities db = new SampleDbEntities();

    public ViewResult Index()
    {
        return View(db.Contacts.ToList());
    }

    public ViewResult Details(int id)
    {
        Contact contact = db.Contacts.Single(c => c.ID == id);
        return View(contact);
    }

    public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Create(Contact contact)
    {
        if (ModelState.IsValid)
        {
            db.Contacts.AddObject(contact);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(contact);
    }

    public ActionResult Edit(int id)
    {
        Contact contact = db.Contacts.Single(c => c.ID == id);
        return View(contact);
    }

    [HttpPost]
    public ActionResult Edit(Contact contact)
    {
        if (ModelState.IsValid)
        {
            db.Contacts.Attach(contact);
            db.ObjectStateManager.ChangeObjectState(contactEntityState.Modified);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(contact);
    }

    public ActionResult Delete(int id)
    {
        Contact contact = db.Contacts.Single(c => c.ID == id);
        return View(contact);
    }

    [HttpPostActionName("Delete")]
    public ActionResult DeleteConfirmed(int id)
    {
        Contact contact = db.Contacts.Single(c => c.ID == id);
        db.Contacts.DeleteObject(contact);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }

}

Existing validation Rules
To implement validations using DataAnnotation attributes in our Model class, we creates a partial class and added the data annotations on it.

[MetadataType(typeof(ContactMetaData))]
public partial class Contact
{
}


the partial class is adorned with the MetadataType attribute which is present in DataAnnotations namespace. This indicated that the meta data for this Model class will be present in ContactMetaData class. So this ContactMetaData class will be the place to put in all our validation logic. This meta data class contains same public properties as that of the Model class it is associated with.
Following validation rules have already been implemented in the previous article
  • All the fields are required.
  • The length of user input should not exceed the length of respective fields.
  • PhoneNumber should contain only numbers.
  • eMail should be in the proper email format.
Implementing Custom Validations
Now in this article, we will try to implement following CUSTOM validations in the same application:
  • Minimum age for entering any contact should be 18 years.
  • Phone numbers for the contact should be unique. i.e. user should not be able to enter same phone number for multiple contacts.
Now let us see how we can use data annotation technique to implement these custom validations. For this we need to create custom validation attributes.
To create custom validation attributes we need to create an Attribute class derived from ValidationAttribute. Let us try to implement the first custom validation rule i.e. "Minimum age for entering any contact should be 18 years". For this let us create a custom attribute class called as MinimumvalueAttribute.

   public class MinimumvalueAttribute : ValidationAttribute
    {

    }

We need to override the IsValid function in this class so as to perform our custom validation. Let us take the specified minimum value in the constructor of the attribute and then we will perform the actual validation in the IsValid function.

public class MinimumvalueAttribute : ValidationAttribute
    {
        private int m_minimumValue;

        public MinimumvalueAttribute(int value)
        {
            m_minimumValue = value;
        }

        protected override ValidationResult IsValid(object valueValidationContext validationContext)
        {
            if (value != null// lets check if we have some value
            {
                if (value is int// check if it is a valid integer
                {
                    int suppliedValue = (int)value;
                    if (suppliedValue < m_minimumValue)
                    {
                        // let the user know about the validation error
                        return new ValidationResult("Minimum value for this field should be " + m_minimumValue);
                    }
                }
            }

            return ValidationResult.Success;
        }
    }

Now we have the custom attribute ready with our custom validation logic. Now let us use this attribute with in the model to associate our custom validation logic with the model property.

class ContactMetaData
{
    /*
    .
    . Other model properties
    .
    */

    [Required(ErrorMessage = "Age is Required")]
    [Minimumvalue(18)] // Our custom attribute
    public int Age { getset; }
}

Now if I run the application and enter a value less than 18, I will get a validation error.


Now on the same lines let us implement our second custom validation rule i.e. "Phone numbers for the contact should be unique". To implement this we will again define our custom attribute and in the IsValid function of the attribute we will check whether the phone number already exists in the database or not.

public class UniquePhoneNumberAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object valueValidationContext validationContext)
        {
            string number = value as string;
            Contact contact = validationContext.ObjectInstance as Contact;

            if (number != null)
            {
                using (SampleDbEntities db = new SampleDbEntities())
                {
                    var contactFound = db.Contacts.FirstOrDefault(item => item.PhoneNumber.Trim().Equals(number.Trim(), StringComparison.OrdinalIgnoreCase));
                    if (contactFound != null && contactFound.ID != contact.ID)
                    {
                        return new ValidationResult("Same phone number exists in the application.");
                    }
                }
            }

            return ValidationResult.Success;
        }
    }

Now let us configure the ContactMetaData class to use this custom attribute for validating the phone number.

class ContactMetaData
    {
        /*
        .
        . Other model properties
        .
        */

        [Required(ErrorMessage = "Phone Number is required")]
        [StringLength(15ErrorMessage = "Phone Number length Should be less than 15")]
        [RegularExpression(@"^[0-9]{0,15}$"ErrorMessage = "PhoneNumber should contain only numbers")]
        [UniquePhoneNumber]  // OUR CUSTOM ATTRIBUTE
        public string PhoneNumber { getset; }
    }


Here we are checking whether the same phone number exist for any other user. If yes then we are showing the user a validation error message. Lets run the application and see the results.


Now we have an application that uses Data annotations to perform custom validations.
Continue Reading →

Monday 25 May 2015

Understanding Angular’s $apply() and $digest()

$apply() and $digest() are two core, and sometimes confusing, aspects of AngularJS. To understand how AngularJS works one needs to fully understand how $apply() and $digest() work. This article aims to explain what $apply() and $digest() really are, and how they can be useful in your day-to-day AngularJS programming.

$apply and $digest Explored
AngularJS offers an incredibly awesome feature known as two way data binding which greatly simplifies our lives. Data binding means that when you change something in the view, the scope model automagically updates. Similarly, whenever the scope model changes, the view updates itself with the new value. How does does AngularJS do that? When you write an expression ({{aModel}}), behind the scenes Angular sets up a watcher on the scope model, which in turn updates the view whenever the model changes. Thiswatcher is just like any watcher you set up in AngularJS:
1
2
3
$scope.$watch('aModel', function(newValue, oldValue) {
  //update the DOM with newValue
});

The second argument passed to $watch() is known as a listener function, and is called whenever the value of aModel changes. It is easy for us to grasp that when the value of aModel changes this listener is called, updating the expression in HTML. But, there is still one big question! How does Angular figure out when to call this listener function? In other words, how does AngularJS know when aModel changes so it can call the corresponding listener? Does it run a function periodically to check whether the value of the scope model has changed? Well, this is where the $digest cycle steps in.
It’s the $digest cycle where the watchers are fired. When a watcher is fired, AngularJS evaluates thescope model, and if it has changed then the corresponding listener function is called. So, our next question is when and how this $digest cycle starts.
The $digest cycle starts as a result of a call to $scope.$digest(). Assume that you change a scopemodel in a handler function through the ng-click directive. In that case AngularJS automatically triggers a$digest cycle by calling $digest(). When the $digest cycle starts, it fires each of the watchers. These watchers check if the current value of the scope model is different from last calculated value. If yes, then the corresponding listener function executes. As a result if you have any expressions in the view they will be updated. In addition to ng-click, there are several other built-in directives/services that let you change models (e.g. ng-model$timeout, etc) and automatically trigger a $digest cycle.
So far, so good! But, there is a small gotcha. In the above cases, Angular doesn’t directly call $digest(). Instead, it calls $scope.$apply(), which in turn calls $rootScope.$digest(). As a result of this, a digest cycle starts at the $rootScope, and subsequently visits all the child scopes calling the watchers along the way.
Now, let’s assume you attach an ng-click directive to a button and pass a function name to it. When the button is clicked, AngularJS wraps the function call within $scope.$apply(). So, your function executes as usual, change models (if any), and a $digest cycle starts to ensure your changes are reflected in the view.
Note$scope.$apply() automatically calls $rootScope.$digest(). The $apply() function comes in two flavors. The first one takes a function as an argument, evaluates it, and triggers a $digest cycle. The second version does not take any arguments and just starts a $digest cycle when called. We will see why the former one is the preferred approach shortly.
When Do You Call $apply() Manually?
If AngularJS usually wraps our code in $apply() and starts a $digest cycle, then when do you need to do call $apply() manually? Actually, AngularJS makes one thing pretty clear. It will account for only those model changes which are done inside AngularJS’ context (i.e. the code that changes models is wrapped inside $apply()). Angular’s built-in directives already do this so that any model changes you make are reflected in the view. However, if you change any model outside of the Angular context, then you need to inform Angular of the changes by calling $apply() manually. It’s like telling Angular that you are changing some models and it should fire the watchers so that your changes propagate properly.
For example, if you use JavaScript’s setTimeout() function to update a scope model, Angular has no way of knowing what you might change. In this case it’s your responsibility to call $apply() manually, which triggers a $digest cycle. Similarly, if you have a directive that sets up a DOM event listener and changes some models inside the handler function, you need to call $apply() to ensure the changes take effect.
Let’s look at an example. Suppose you have a page, and once the page loads you want to display a message after a two second delay. Your implementation might look something like the JavaScript and HTML shown in the following listing.
<body ng-app="myApp">
    <div ng-controller="MessageController">
        Delayed Message: {{message}}
    </div>
</body>

<script>
    /* What happens without an $apply() */

    angular.module('myApp', []).controller('MessageController', function ($scope) {

        $scope.getMessage = function () {
            setTimeout(function () {
                $scope.message = 'Fetched after 3 seconds';
                console.log('message:' + $scope.message);
            }, 2000);
        }

        $scope.getMessage();

    });
</script>

Output:
Delayed Message:

By running the example, you will see that the delayed function runs after a two second interval, and updates the scope model message. Still, the view doesn’t update. The reason, as you may have guessed, is that we forgot to call $apply() manually. Therefore, we need to update our getMessage() function as shown below.
<body ng-app="myApp">
    <div ng-controller="MessageController">
        Delayed Message: {{message}}
    </div>
</body>

<script>
    /* What happens with $apply */
    angular.module('myApp', []).controller('MessageController', function ($scope) {

        $scope.getMessage = function () {
            setTimeout(function () {
                $scope.$apply(function () {
                    //wrapped this within $apply
                    $scope.message = 'Fetched after 3 seconds';
                    console.log('message:' + $scope.message);
                });
            }, 2000);
        }

        $scope.getMessage();

    });
</script>

Output:
Delayed Message: Fetched after 3 seconds
If you run this updated example, you can see the view update after two seconds. The only change is that we wrapped our code inside $scope.$apply() which automatically triggers $rootScope.$digest(). As a result the watchers are fired as usual and the view updates.
Note: By the way, you should use $timeout service whenever possible which is setTimeout() with automatic $apply() so that you don’t have to call $apply() manually.
Also, note that in the above code you could have done the model changes as usual and placed a call to$apply() (the no-arg version) in the end. Have a look at the following snippet:
1
2
3
4
5
6
7
$scope.getMessage = function() {
  setTimeout(function() {
    $scope.message = 'Fetched after two seconds';
    console.log('message:' + $scope.message);
    $scope.$apply(); //this triggers a $digest
  }, 2000);
};
The above code uses the no-arg version of $apply() and works. Keep in mind that you should always use the version of $apply() that accepts a function argument. This is because when you pass a function to$apply(), the function call is wrapped inside a try...catch block, and any exceptions that occur will be passed to the $exceptionHandler service.

How Many Times Does the $digest Loop Run?
When a $digest cycle runs, the watchers are executed to see if the scope models have changed. If they have, then the corresponding listener functions are called. This leads to an important question. What if a listener function itself changed a scope model? How would AngularJS account for that change?
The answer is that the $digest loop doesn’t run just once. At the end of the current loop, it starts all over again to check if any of the models have changed. This is basically dirty checking, and is done to account for any model changes that might have been done by listener functions. So, the $digest cycle keeps looping until there are no more model changes, or it hits the max loop count of 10. It’s always good to stay idempotent and try to minimize model changes inside the listener functions.
Note: At a minimum, $digest will run twice even if your listener functions don’t change any models. As discussed above, it runs once more to make sure the models are stable and there are no changes.
Conclusion
I hope this article has clarified what $apply and $digest are all about. The most important thing to keep in mind is whether or not Angular can detect your changes. If it cannot, then you must call $apply()manually.
Continue Reading →

Topics

ADFS (1) ADO .Net (1) Ajax (1) Angular (43) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (47) CD (1) CI (2) CloudComputing (2) Coding (7) CQRS (1) CSS (2) Design_Pattern (6) DevOps (4) DI (3) Dotnet (8) DotnetCore (16) Entity Framework (2) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) Lamda (3) Linq (11) microservice (3) Mongodb (1) MVC (46) NodeJS (8) React (11) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (1) UI (1) UnitTest (1) WCF (14) Web Api (15) Web Service (1) XMl (1)

Dotnet Guru Archives