How to make WinForm perform Model validation?

How to make WinForm perform Model validation? If you have experience in asp.net mvc development, you will know that we can call ModelState.IsValid to verify the model. This is to verify the legality of the data submitted by the client from a security or business perspective.

WinForm perform Model validation

For Winform development, we need to encapsulate and provide similar functions by ourselves. For Winform development, we need to encapsulate ourselves to provide similar functions. In addition, you can also find similar posts on stackoverflow. This article also shares how I did it based on these methods.For Winform development, we need to encapsulate ourselves to provide similar functions. In addition, you can also find similar posts on stackoverflow. This article also shares how I did it based on these methods.

The following content is derived from a post on c-sharpcorner.com. I think this post is very good and can help you learn some useful knowledge.

Validation Forms In DataAnnotations

In this second article, we will learn all validation forms in DataAnnotation. We will review Validator class with all its structure. The first part can be found on the following link.

DataAnnotation enables us to work with positive programming. In other words, it allows us anticipate exceptions for problems in our business classes or domain classes. It provides better performance. The negative programming version also exists.

  • Positive – TryValidate.
  • Negative – Validate.

On this link, you will get the information about Exceptions and Performance.

The examples class

The class for all examples will be a new version of the class created in part I.

public class Customer  
{  
    [Required(ErrorMessage = "{0} is mandatory")]  
    [MaxLength(50, ErrorMessage = "The {0} can not have more than {1} characters")]  
    public string Name { get; set; }  
  
    [Range(typeof(DateTime), "01/01/2016", "01/01/2050",  
        ErrorMessage = "Valid dates for the Property {0} between {1} and {2}")]  
    public DateTime EntryDate { get; set; }  
  
    public string Password { get; set; }  
  
    [Compare("Customer.Password", ErrorMessage = "The fields Password and PasswordConfirmation should be equals")]  
    public string PasswordConfirmation { get; set; }  
  
    [Range(0, 150, ErrorMessage = "The Age should be between 0 and 150 years")]  
    public int Age { get; set; }  
}  

These are principal validation classes.

ValidationResult

ValidationResult is a container for class validation results. For more info, go here.

ValidationResult has 2 properties

  • ErrorMessages .- String readonly property with the information error description.
  • MemberNames.- IEnumerable<string> readonly property with the property name on error.

We have written an extension method to print the validation errors.

public static string ToDescErrorsString(this IEnumerable<ValidationResult> source, string mensajeColeccionVacia = null)  
{  
    if (source == null) throw new ArgumentNullException(nameof(source), $"The property {nameof(source)}, doesn't has null value");  
   
    StringBuilder resultado = new StringBuilder();  
   
    if (source.Count() > 0)  
    {  
        resultado.AppendLine("There are validation errors:");  
        source.ToList()  
            .ForEach(  
                s =>  
                    resultado.AppendFormat("  {0} --> {1}{2}", s.MemberNames.FirstOrDefault(), s.ErrorMessage,  
                        Environment.NewLine));  
    }  
    else  
        resultado.AppendLine(mensajeColeccionVacia ?? string.Empty);  
   
    return resultado.ToString();  
}  

Validator class

This is the static helper class. The Validator class allows you to execute validation on objects, properties, and methods. You can get more information from this link.

We can separate its methods in two groups, as we saw earlier. POSITIVE PROGRAMMING (Returns bool value and we have a ICollection<ValidationResult> parameter) The return property bool is a validation result.The ICollection<ValidationResult> argument contains details of validation errors. If the validation doesn’t have errors, this collection will be empty.
TryValidateObject

public static bool TryValidateObject(object instance, ValidationContext validationContext, ICollection<ValidationResult> validationResults);  
public static bool TryValidateObject(object instance, ValidationContext validationContext, ICollection<ValidationResult> validationResults, bool validateAllProperties);  

This method validates all objects. TryValidateObject has an overload with a bool argument validateAllProperties that is enabled in case when validation error continues with the validation of all properties.

Arguments

  • Instance The instance of class to validate.
  • ValidationContext The context that describes the object to validate.
  • ValidationResults The collection of validation results descriptions.
  • ValidateAllProperties Enabled continues to validate all properties.

Example

public static void TryValidateObjectExample1()  
{  
    /// 1.- Create a customer  
    var customer = new Customer  
    {  
        Name                 = string.Empty,  
        EntryDate            = DateTime.Today,  
        Password             = "AAAA",  
        PasswordConfirmation = "BBBB",  
        Age                  = -1  
    };  
    /// 2.- Create a context of validation  
    ValidationContext valContext = new ValidationContext(customer, null, null);  
    /// 3.- Create a container of results  
    var validationsResults = new List<ValidationResult>();  
    /// 4.- Validate customer  
    bool correct = Validator.TryValidateObject(customer, valContext, validationsResults, true);  
   
    Console.WriteLine(validationsResults.ToDescErrorsString("Without Errors !!!!"));  
    Console.Read();  
}  

In this example, we have done the second overload with true value (ValidateAllProperties).

Result

WinForm perform Model validation
WinForm perform Model validation

We have validated all customer properties.

If we change the last argument to false, it only validates the first property on error.

public static void TryValidateObjectExample2()  
{  
    /// 1.- Create a customer  
    var customer = new Customer  
    {  
        Name                 = string.Empty,  
        EntryDate            = DateTime.Today,  
        Password             = "AAAA",  
        PasswordConfirmation = "BBBB",  
        Age                  = -1  
    };  
    /// 2.- Create a context of validation  
    ValidationContext valContext = new ValidationContext(customer, null, null);  
    /// 3.- Create a container of results  
    var validationsResults = new List<ValidationResult>();  
    /// 4.- Validate customer  
    bool correct = Validator.TryValidateObject(customer, valContext, validationsResults, false);  
   
    Console.WriteLine(validationsResults.ToDescErrorsString("Without Errors !!!!"));  
    Console.Read();  
}  

WinForm perform Model validation

Result

WinForm perform Model validation
WinForm perform Model validation

TryValidateProperty

public static bool TryValidateProperty(object value, ValidationContext validationContext, ICollection<ValidationResult> validationResults);  

WinForm perform Model validation

It has only one overload. It has the same parameters as of TryValidateObject, but the first object parameter does match with one property to validate and the method, therefore, validates properties.

public static void TryValidatePropertyExample()  
{  
    /// 1.- Create a customer  
    var customer = new Customer  
    {  
        Name                 = string.Empty,  
        EntryDate            = DateTime.Today,  
        Password             = "AAAA",  
        PasswordConfirmation = "BBBB",  
        Age                  = -1  
    };  
    /// 2.- Create a context of validation  
    ValidationContext valContext = new ValidationContext(customer, null, null)  
    {  
        MemberName = "Age"  
    };  
    /// 3.- Create a container of results  
    var validationsResults = new List<ValidationResult>();  
    /// 4.- Validate customer Age Property  
    bool correct = Validator.TryValidateProperty(customer.Age, valContext, validationsResults);  
   
    Console.WriteLine(validationsResults.ToDescErrorsString("Without Errors !!!!"));  
    Console.Read();  
}  

WinForm perform Model validation

When we instance the ValidationContext object, we give value to string property MemberName with the property name to validate.

The TryValidateProperty and the TryValidateObject are equal. The only change is the first parameter. The TryValidateProperty will have to call the property value.

Result

WinForm perform Model validation
WinForm perform Model validation

TryValidateValue

public static bool TryValidateValue(object value, ValidationContext validationContext, ICollection<ValidationResult> validationResults, IEnumerable<ValidationAttribute> validationAttributes);  

WinForm perform Model validation

TryValidateValue validates a value through ValidationAttribute collection. This is practical to reuse our ValidationAttributes and for us to be disabused of the if terms.

public static void TryValidateValueExample()  
{  
    /// 1.- Create value  
    string myPwd = "33223";  
    /// 2.- Create ValidationsAttributes  
    MinLengthAttribute minLengthAtribute = new MinLengthAttribute(8) { ErrorMessage = "{0} must have {1} caracters minimum" };  
    RequiredAttribute requieredAttribute = new RequiredAttribute     { ErrorMessage = "{0} is mandatory" };  
    List<ValidationAttribute> atributes  = new List<ValidationAttribute>() { minLengthAtribute, requieredAttribute };  
    /// 3.- Create a context of validation  
    ValidationContext valContext = new ValidationContext(myPwd, null, null)  
    {  
        MemberName = "myPwd"  
    };  
    /// 4.- Create a container of results  
    var validationsResults = new List<ValidationResult>();  
    /// 5.- Validate myPwd value  
    bool correct = Validator.TryValidateValue(myPwd, valContext, validationsResults, atributes);  
   
    Console.WriteLine(validationsResults.ToDescErrorsString("Without Errors !!!!"));  
    Console.Read();  
}  

WinForm perform Model validation

 We have created the attributes in code, because we will validate a value and we don’t have properties to mark in the class declaration.

Result

WinForm perform Model validation
WinForm perform Model validation

NEGATIVE PROGRAMMING (throw ValidationException and it hasn’t ICollection<ValidationResult argument )  These methods remove the word Try in your names. They are void methods. If the validation fails, it will throw a ValidationException.

They don’t have an ICollection<ValidationResult> argument. This information will have an inside exception and it isn’t a collection. But, it is a simple ValidationResult because if validation fails, it doesn’t verify the remaining properties.

public static void ValidateObject(object instance, ValidationContext validationContext);  
public static void ValidateObject(object instance, ValidationContext validationContext, bool validateAllProperties);  
public static void ValidateProperty(object value, ValidationContext validationContext);  
public static void ValidateValue(object value, ValidationContext validationContext, IEnumerable<ValidationAttribute> validationAttributes);

WinForm perform Model validation

Example

public static void ValidateObjectExample()  
{  
    /// 1.- Create a customer  
    var customer = new Customer  
    {  
        Name                 = string.Empty,  
        EntryDate            = DateTime.Today,  
        Password             = "AAAA",  
        PasswordConfirmation = "BBBB",  
        Age                  = -1  
    };  
    /// 2.- Create a context of validation  
    ValidationContext valContext = new ValidationContext(customer, null, null);  
   
    try  
    {  
        /// 3.- Validate customer  
        Validator.ValidateObject(customer, valContext, true);  
    }  
    catch (ValidationException ex)  
    {  
        /// 4.- Print Validations Results  
        ValidationResult s = ex.ValidationResult;  
   
        Console.WriteLine("There are validation errors:");  
        Console.WriteLine("  {0,-20} --> {1}{2}", s.MemberNames.FirstOrDefault(), s.ErrorMessage,  
                        Environment.NewLine);  
    }  
   
              
    Console.Read();  
}  

Result

image005
WinForm perform Model validation

The other methods are same as the ‘Try’ version.

Considerations and tests

Remember, we can use the extension method of Chapter I.

You have the source code to test the examples.

Leave a Comment