Pranay Rana: March 2015

Saturday, March 7, 2015

Validation in any type Application using DataAnnotation

DataAnotation NameSpace

System.ComponentModel. DataAnnotation namespace that provides set of attributes classes used for decorating class property with it, which is useful for validating class object. Besides attribute classes it also provide set of class which is helpful for validating class (Ex. Validator, ValidationContext, VlidationResult i.e. all classes with start with Validat**** ).

Below image show the all classes provided by DataAnnotation



Image shows the all classes not related to validation.

Find more about each class on MSDN : https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28v=vs.95%29.aspx

How to use Attribute

Before start look this for creating custom attribute : Custom Validation Attribute Specific to Entity

Now to use Attribute in your entity you need to decorate your property of entity with attribute as below :

    public class BankAccount
    {

        public enum AccountType
        {
            Saving,
            Current
        }

        [Required(ErrorMessage="First Name Required")]
        [MaxLength(15,ErrorMessage="First Name should not more than 1`5 character")]
        [MinLength(3,ErrorMessage="First Name should be more than 3 character")]
        public string AccountHolderFirstName { get; set; }

        [Required(ErrorMessage="Last Name Required")]
        [MaxLength(15,ErrorMessage="Last Name should not more than 1`5 character")]
        [MinLength(3,ErrorMessage="Last Name should be more than 3 character")]
        public string AccountHolderLastName { get; set; }

        [Required]
        [RegularExpression("^[0-9]+$", ErrorMessage = "Only Number allowed in AccountNumber")]
        public string AccountNumber { get; set; }

        public AccountType AcType { get; set; }

        [AccountBalaceCheckAttribute]
        public double AccountBalance { get; set; }
    } 

As in above code BankAccount entity property decorated with the Attribute and also provided with the proper error message.

In code AccountBalance is property is decorated with Entity Specific custom validation attribute. To read about more please refer custom attribute link listed above.

How to validate

To validate entity DataAnnotation provides class called Validator, which allow to validate entity as listed in below code.

public class GenericValidator 
    {
        public static bool TryValidate(object obj, out ICollection results)
        {
            var context = new ValidationContext(obj, serviceProvider: null, items: null);
            results = new List();
            return Validator.TryValidateObject(
                obj, context, results,
                validateAllProperties: true
            );
        }
    }

Above code shows code for GenericValidator class , which is class to validate any entity. Class used to avoid writing code again and again when doing validation.

Above code class make use of Validator class with it TryValidateObject method which takes ValidationContext class object as input.

Below code shows how to use GenericValidator class for validating entity.

static void Main(string[] args)
        {
            var bankAccount = new BankAccount();
            ICollection lstvalidationResult;

            bool valid = GenericValidator.TryValidate(bankAccount, out lstvalidationResult);
            if (!valid)
            {
                foreach (ValidationResult res in lstvalidationResult)
                {
                    Console.WriteLine(res.MemberNames +":"+ res.ErrorMessage);
                }
                
            }
            Console.ReadLine();
        }

Output 

Conclusion

ValidationAttribute is doing one way to achieve Validation (Aspect Oriented Programming) with the help of attribute. And validation attribute provided in DataAnnotation namespace can be used in any time of application to do validation of entity.

Complex Custom Validation Attribute Specific to Entity

System.Componentmodel.DataAnnotation NameSpace

System.Componentmodel.DataAnnotation is namespace in .net framework provide set of the attribute classes. This attribute classes used for decorating property of the user defined entity and validate entity.

Find more about each class on MSDN : https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28v=vs.95%29.aspx

ValidationAttribute: -

Most of all required attributes for validation is provided in the DataAnnotation namespace but there are some complex validation required to validate entity required to define by developer of itself.

ValidationAttribute is class in DataAnnotation namespace allow to create custom attribute as per the need to developer to validate entity.

Following is implementation of custom validation attribute:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class AccountBalaceCheckAttribute : ValidationAttribute
{
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            ValidationResult result = ValidationResult.Success;
            string[] memberNames = new string[] { validationContext.MemberName };

            decimal val = Convert.ToDecimal(value);

            BankAccount account = (BankAccount)validationContext.ObjectInstance;

            if (account.AcType == BankAccount.AccountType.Saving && val < 500)
                result = new ValidationResult(string.Format(this.ErrorMessage, 500),memberNames);
            else if (account.AcType == BankAccount.AccountType.Current && val < 1000)
                result = new ValidationResult(string.Format(this.ErrorMessage, 1000), memberNames);


            return result;
        }
} 

How to use it

 
public class BankAccount
{

   public enum AccountType
   {
      Saving,
      Current
   }

   public AccountType AcType { get; set; }

   [AccountBalaceCheckAttribute(ErrorMessage = "Account Balance should have value more than {0}")]
   public double AccountBalance { get; set; }
}

In this example attribute is defined for the specific entity BankAccount entity. Requirement for defining this attribute is “Based on value of AccountType , account should hold minimum balance.”

So for that here, BankAccount object is accessed in IsValid method and then by checking value of the Account type attribute validates AccountBalance value.

Other Things to note here are :
  1. Attribute class is Sealed and Derived from the ValidationAttribute.
  2. Custom attribute class override IsValid method of the base ValidationAttribute class.
  3. Attribute can be used for property and not allowed to define attribute multiple time on property.
To find how to define attribute not specific to entity follow MSDN: https://msdn.microsoft.com/en-us/library/cc668224%28v=vs.140%29.aspx

Random Number in MultiThreading

Random Number in MultiThreading 

 Random Number

Random number class in .net framework used for generating random numbers. Random number class allows creating random number instance by following two constructors
  1. Random() – it make use of system clock as seed value and create instance.
    As random make use of System clock as input when creating two instances as below
                Random rand = new Random();
                Random rand1 = new Random();
    
    It use same system clock input so output of above when doing below code
                Console.WriteLine(rand.Next());
                Console.WriteLine(rand1.Next());
    
    generate same random number. Example both line of code write 10 on console.

  2. Random(int32 seed) – it make use of input integer value and create instance.
    As random make use integer value as input when creating two instance with different input
                  Random rand = new Random(30);
                  Random rand1 = new Random(40);
    
    so output of above when writing below code
           Console.WriteLine(rand.Next());
                  Console.WriteLine(rand1.Next());
    
    Generate different random number.

So by above two way of creating random instance shows that seed value plays important role in creating random number instance.

Random In Multi-Threading

Following is line of code that used as simulator i.e following line of code used to generate which used by other application.
        static void Main(string[] args)
        {   
            Program program = new Program();
            
            char[] publish = new char[] { 'r', 'v'};

            List<Task> tasks = new List<Task>();
            while (true)
            {
                Console.WriteLine("Press any key to publish new data and 'n' to exit");
                char rchar = Convert.ToChar(Console.Read());
                Console.ReadLine();
                if (rchar == 'n')
                    break;

                foreach (char c in publish)
                {
                    if (c == 'r')
                        tasks.Add(Task.Run(() =>program.PublishRateOrVolume(c)));
                    else if (c == 'v')
                        tasks.Add(Task.Run(() =>program.PublishRateOrVolume(c)));
                }

                try
                {
                    Task.WaitAll(tasks.ToArray());
                    foreach (Task<string> t in tasks)
                        Console.WriteLine(t.Result);
                }
                catch (AggregateException ae)
                {
                    Console.WriteLine(ae.ToString());
                }
                tasks.Clear();
            }
            tasks = null;
        }

Above line of code create two tasks in that one task generates rate date and another task generates volume data for publishing data. Things to note in above code is both the task calling same method but with the different input value ‘r’ (rate) and ‘v’ (volume).

        private string PublishRateOrVolume(char publishChar)
        {
            StringBuilder sb = new StringBuilder();
            char[] inputchar = new char[] { '1', '2'};
            string clientName = string.Empty;
            
            var random = new Random();

            try
            {
                foreach (char c in inputchar)
                {
                    if (c == '1')
                        clientName = "Test 1";
                    if (c == '2')
                        clientName = "Test 2";
                 
                    var data = random.NextDouble() * random.Next(0, 500);
                    
                    if (publishChar == 'v')
                        sb.AppendLine("VOLUME Data Publish by Client :" + clientName + " Volume :" + data);
                    else if (publishChar == 'r')
                       sb.AppendLine("RATE Data Publish by Client :" + clientName + " Rate :" + data);
                }
                return sb.ToString();
            }
            finally
            {
                random = null;
                inputchar = null;
                sb = null;
            }
        }

Above code function, called by different task with respected argument to generate volume and rate data. Each task generates volume and rate data for two clients (test 1 and test 2). Things to note in code function creates Random class instance for generating random data.

Above line of code generate following output



Problem with the output is Program generate same data for volume and rate for each client which is not expected, expected result is it generate different random values of rate and value for each client.

What is the issue?

Issue with above code is random number instance get created by two different task almost with the same seed value, as the seed value for both random instance is same it generate same values. It’s already discussed above in random class constructor example.

Following is solution to the problem of random number in multithreading environment
  1. Add Delay between creating two task
    As random instance make use of system clock value adding delay between creation of two task gives different seed value to default random class instance.
    So the code for this is
      foreach (char c in publish)
      {
         if (c == 'r')
            tasks.Add(Task.Run(() =>program.PublishRateOrVolume(c)));
         else if (c == 'v')
            tasks.Add(Task.Run(() =>program.PublishRateOrVolume(c)));
         Thread.Sleep(50);
      }
    

    With the Thread.Sleep small delay is get added between creating of task and as there is delay two instance of random number receive different seed.

    But problem with this solution is it requires to add delay, so if there are more than two task it will create problem, also it cause problem in mission critical application where time is important.

  2. Use only one instance of random class
    According to this solution only one instance of random number class get created and shared between multiple threads. So the code is
     
           static void Main(string[] args)
           {
      Random random = new Random();
      // code as it is
      foreach (char c in publish)
                    {
                        if (c == 'r')
                            tasks.Add(Task.Run(() => program.PublishRateOrVolume(c, random)));
                        else if (c == 'v')
                            tasks.Add(Task.Run(() => program.PublishRateOrVolume(c, random)));
                    }
              }
                 //code as it is
            }
    private string PublishRateOrVolume(char publishChar, Random random)
           {
      //code as it is 
    }
    

    As in code one random instance is created in main method and same instance used by both task to generate random number.

    But problem with this solution is one random number instance is shared between two tasks and random number class is not thread safe.
    As random number instance is not thread safe when two thread call next() method at same time it will generate 0 as output and then afterwards random number generates 0 and not useful. To check try below example
     
                Random rand = new Random();
    
                Parallel.For(0, 1000000, (i, loop) =>
                {
                    if (rand.Next() == 0) loop.Stop();
         });
    

     To avoid problem make use of lock when accessing random instance via it methods like next(), netxtDouble().
     object lockobj = new object();
            lock (lockobj)
            {
                 data= rand.NextDouble() * rand.Next(0, 500);
            }
    

    It resolves issue but problem is lock statement slow down application when there are more number of threads.

  3. Make use of ThreaLocal<T> with the different seed value
    This solution make use of ThreaLocal<T> class, it allows creating local variable for each thread/task. Read more about ThreadLocal class : https://msdn.microsoft.com/en-us/library/dd642243%28v=vs.110%29.aspx
    So the code with ThreaLocal<T> as below
    private string PublishRateOrVolume(char publishChar)
    {
         var random = new ThreadLocal<Random>(() => new
                          Random(Guid.NewGuid().GetHashCode()));
        //code as it is 
        var data = random.Value.NextDouble() * random.Value.Next(0, 500); 
       //code as it is
    }
    
    In code random instance created using ThreaLocal<T> class means each task receive its own local instance of Random class.
    Another thing to note in code is seed value passed when creating Random instance. Seed value is HashCode value of the Guid instance i.e. each time new instance receives new seed value.

Conclusion

Random class is not thread safe and above is three solution to make it thread safe but out of three the third solution is perfect and fits as thread safe solution.

Please find attached code which having all three solution.