Click here to Skip to main content
15,885,178 members
Articles / Programming Languages / C#

Data Binding in Silverlight with RIA and Entity Framework – Part 3 (Validating Input Data)

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
12 Apr 2011CPOL5 min read 10.8K  
Data binding in Silverlight with RIA and Entity Framework - validating input data

Validation is a integral part of software development. In Silverlight, validation approach has been changed or you can say that it has evolved from version 2. So this post will highlight the options available for validation with continuation of StatesOfIndia application.

Article Series

Extending StatesOfIndia Application

In continuation to the SOI application, we will add validation to the user input. Collectively, I want to put validation for the following logic.

Basic Validation

  • State Name Mandatory and Length should not exceed more than 15
  • Data type Validation for Population, Literacy, No Of District, Area which should allow Numeric Entry only
  • Website URL Validation
  • Define Population, Literacy Range

Adv. Validation

  • Cross Check State Name whether it exists in database (Cross Property Validation)

Validation In RIA With Silverlight

There are many ways of validating the User input. Either you can do it at Client side without any server round-trip or request or else Validation at server side or async validation. It depends on your choice and scenario. Prior version of Silverlight primarily depended on Exception Based validation and with current available solution, it does not make sense to discuss so I have skipped Exception Based Validation.

Silverlight 4 exposes basically the following methods of validation:

  • Using Metadata Attribute
  • Code Behind Approach (Can be used at Client side using Async Operations or else Server side only)
With Attribute Metadata

As mentioned earlier, the validation rule can be defined at entity level and their member. To do so, make sure that you have selected the Metadata generation option while adding the DomainService. This option will add a metadata class “DomainService_SOI.metadata.cs” .Checking the class file, we can find the entity and its members.

Data Binding in Silverlight with RIA and Entity Framework – Part 3 ValidatingData) Data Binding in Silverlight with RIA and Entity Framework – Part 3 ValidatingData)

Now suppose I want to enforce stateName as Mandatory and the character length of the state should not exceed 15, then:

C#
[Required(AllowEmptyStrings=false,ErrorMessage="State Name cannot be empty")] 
[StringLength(15)] 
public string StateName { get; set; }

Now build your application and check the generated code at client side Silverlight project.

Data Binding in Silverlight with RIA and Entity Framework – Part 3 ValidatingData)

Propagated Client Side Validation Code

C#
/// <summary> 
/// Gets or sets the ‘StateName’ value. 
/// </summary> 
[DataMember()] 
[Required(ErrorMessage="State Name cannot be empty")] 
[StringLength(15)] 
public string StateName 
{ 
get 
{ 
return this._stateName; 
} 
set 
{ 
if ((this._stateName != value)) 
{ 
this.OnStateNameChanging(value); 
this.RaiseDataMemberChanging("StateName"); 
this.ValidateProperty("StateName", value); 
this._stateName = value; 
this.RaiseDataMemberChanged("StateName"); 
this.OnStateNameChanged(); 
} 
} 
}

If you notice, then you will find the attributes we added to the model metadata member is propagated to client side automatically. We can show custom error message by providing the Error Message Attribute as below:

C#
[Required(AllowEmptyStrings=false,ErrorMessage="State Name cannot be empty")]

Following are some of the other attributes for property level validation defined in System.ComponentModel.DataAnnotations namespace are as follows:

So as mentioned above, the SOI application basic validations can be achieved with the following attributes.

State Name Mandatory and Length Should Not Exceed more than 15

C#
[Required(AllowEmptyStrings=false,ErrorMessage="State Name cannot be empty")] 
[StringLength(15)] 
public string StateName { get; set; }

As the validation needs to be fired on textbox leave event, we need to do some ground clearance work although against wish :), check my last blogpost.

Website URL Validation

C#
[DataType(DataType.Url)] 
public string Website { get; set; }

Define Population, Literacy Range

C#
[Range(0,100)]
public Nullable<int> Literacy { get; set; }

Data type Validation for Population, Literacy, No Of District, Area which should allow Numeric Entry only. As we need to restrict user while entering the value, I have handled it in code behind at KeyDown event.

Custom Attribute Validation

Although default attribute provides almost all standard way of validation, sometimes custom validations are unavoidable. For example, here the wiki info content must be more than 3 words. To add custom validation, keep the following points in mind.

  • Add a class which will contain the validation logic at server side
  • Make sure that your class will have a shared.cs extension so that the validation can be propagated to the client side

Let's do it. Add class StateValidations.shared.cs to the Server side project of the solution.

Data Binding in Silverlight with RIA and Entity Framework – Part 3 ValidatingData)

The custom validation check is a simple C# code named "ValidInfo" which is a static member and takes ValidationContext as argument other than the value need to be checked. ValidationContext represents state and service of the object to be validated. Once the validation succeeds, it returns a ValidationResult object.

C#
namespace StatesOfIndia.Web.Shared 
{ 
public class StateValidations 
{ 
public static ValidationResult ValidInfo(string description, ValidationContext context) 
{ 
//Validation Logic 
if (String.IsNullOrEmpty(description)) 
{ 
return ValidationResult.Success; 
} 
string[] words = description.Split(new char[] { ‘ ‘, ‘\t’, ‘\n’, ‘\r’, }, 
StringSplitOptions.RemoveEmptyEntries); 
if (words.Length > 3) 
{ 
return ValidationResult.Success; 
} 
//return Validation Error 
return new ValidationResult("The Wiki Info must be meaningful.", 
new string[] { "WikiIntro" }); 
} 
} 
}

Once you built the project, check with the Silverlight client side project. The Generated Code stub will now have the same shared.cs.

image

To implement the custom validator, let's move to our TasksDomainService.metadata.cs at server side project and add the following attribute to the WikiInfo property.

C#
[CustomValidation(typeof(StateValidations),"ValidInfo")] 
public string WikiIntro { get; set; }

When CustomValidation attribute applied to a property, the attribute is invoked whenever a value is assigned to that property. When it is applied to a method, the attribute is invoked whenever the program calls that method. When it is applied to a method parameter, the attribute is invoked before the method is called. A more detailed article can be found here.

Let's run the application and check with the result.

Data Binding in Silverlight with RIA and Entity Framework – Part 3 ValidatingData)

Asynchronous Validation to Check Whether State Exists Against Database

In SOI app, it's pretty normal to check the State whether it exists in database before adding it to the collection. Instead of validating it on button click, it will be nice if the same can be validated on the fly, once the user leaves the state Textbox. For the validation to succeed, it needs to hit back to the database collection and needs to verify.

Ahhh it's quite exciting. Let's check.

  • Add a new Method/Operation to domain service class “DomainService_SOI.cs”, named “IsStateExist”. As you can find below, the method has an [INVOKE] attribute which lets the operations run without deferred execution. More details can be found here.)
    C#
    [Invoke] 
    //Custom Validation for Async Operation 
    public bool IsStateExist(string stateName) 
    { 
    bool isStateExist = false; 
    isStateExist = GetStates().Any(state => state.StateName == stateName); 
    return isStateExist; 
    }
  • Add a custom validator method as shared code, as we have done in the above “ValidInfo” case.
    C#
    public static ValidationResult AsyncValidateState(string stateName, ValidationContext valContext) 
    { 
    ValidationResult error = new ValidationResult( 
    "State with specified name already exists", 
    new string[] { valContext.MemberName }); 
    //Code For Client Side silverlight project 
    #if SILVERLIGHT 
    DomainService_SOI context = new DomainService_SOI(); 
    InvokeOperation<bool> IsExist = context.IsStateExist(stateName); 
    IsExist.Completed += (s, e) => 
    { 
    if (!IsExist.HasError && IsExist.Value) 
    { 
    Entity entity = (Entity)valContext.ObjectInstance; 
    entity.ValidationErrors.Add(error); 
    } 
    }; 
    #endif 
    return ValidationResult.Success; 
    }
  • Then, add the CustomValidation attribute to the metadata code.
    C#
    [CustomValidation(typeof(StateValidations), "AsyncValidateState")] 
    public string StateName { get; set; }

Let's run the application and let the validation do its work:

Data Binding in Silverlight with RIA and Entity Framework – Part 3 ValidatingData)

Conclusion

Hope this post gives you a fair idea about data validation. Keep learning :).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Microsoft
India India
Nothing special .. I like challenges and love my critics.

Microsoft | Bangalore | India

Blog : http://manaspatnaik.com/blog

Twitter@manas_patnaik

Comments and Discussions

 
-- There are no messages in this forum --