In my previous post I’ve tried to explain RadGridView validation mechanism and support for 2 layers of validation (UI and Data) for a property/cell level. RadGridView exposes same events on a row level too (RowValidating, RowValidated and RowEditEnded). Since this theory you can find on our online help I’ll begin with the interesting stuff - asynchronous validation example.

 

I’m glad to announce that with the next (2010.Q2) version RadGridView will support asynchronous validation.

By asynchronous validation I mean that RadGridView can save a value in its collection and from somewhere (server side usually) to receive a message that this value doesn’t pass some business requirements. This means that RadGridView will fire all events related to editing and validation logic (cell/rowValidating, cell/rowValidated, cell/rowEditEnded) and will leave edit mode. When such an error message occurs then RadGridView will show the error accordingly.

 

N.B. Keep in mind that RadGridView will not scroll wrong items (cells) into view, only if corresponding UI elements (cells and rows) are visible (or become visible) they will update their validation status.

 

For Silverlight async validation will be provided by INotifyDataErrorInfo interface. While for WPF we will need some tricky combination of interfaces INotifyPropertyChanged (notify part) and IDataErrorInfo  (error message part). For an example I’ll create a Silverlight application which consumes data with RIA services, because RIA services Entity object implements INotifyDataErrorInfo interface natively.

 

I will not go over the steps for creating the ADO.NET Entity Data Model and the Domain Service Class. In case you are not familiar with them, you should start with Brad Abrams’ series of blog posts and read this blog after that. In addition you can take a look at this very nice blog post by Jeff Handley for a reference how to implement asynchronous validation for Silverlight. You can also easily create RIA services applications via Telerik Open access ORM.

 

My example uses Customers table from Northwind database and requires SQL Server EXPRESS edition. For other instances of SQL Server you should edit connection string within Web.config file.

 

We will validate “City” field with a very trivial check – city name should be longer than 3 letters. Now we have aim and let see the necessary steps to hit it.

 

1. According to Jeff Handley’s blog we create a method on a service side which we will use for validation:

 

[EnableClientAccess()]

    public class NorthwindDomainService : LinqToEntitiesDomainService<NorthwindEntities>

    {

        [Invoke]

        public bool IsCityValid(string city)

        {

            // For the sake of example we just simulate async response

            System.Threading.Thread.Sleep(2000);

            return (city.Length > 3);

        }

 

2. We create a class named CustomerValidator.shared.cs “shared” word is very critical, because otherwise the compiler will not create same class in the client application. Here is the code of the class:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.ComponentModel.DataAnnotations;

 

#if SILVERLIGHT

using System.ServiceModel.DomainServices.Client;

#endif

 

namespace AsyncValidationExample.Web

{

    public static class CustomerValidator

    {

        public static ValidationResult IsCityValid(string city, ValidationContext validationContext)

        {

            ValidationResult errorResult = new ValidationResult("City name should be longer than 3 letters!", new string[] { validationContext.MemberName });

 

#if !SILVERLIGHT

            NorthwindDomainService service = new NorthwindDomainService();

 

            if (!service.IsCityValid(city))

            {

                return errorResult;

            }

 

#else

 

            NorthwindDomainContext context = new NorthwindDomainContext();

 

 

            InvokeOperation<bool> availability = context.IsCityValid(city);

 

            availability.Completed += (s, e) =>

            {

                if (!availability.HasError && !availability.Value)

                {

                    Entity entity = (Entity)validationContext.ObjectInstance;

                    if (!entity.ValidationErrors.Any(v => v.ToString() == errorResult.ToString()))

                    {

                        entity.ValidationErrors.Add(errorResult);

                    }

                }

            };

 

#endif

            return ValidationResult.Success;

        }

    }

}

 

3. We use this class to validate Customer object via DataAnnotations “CustomValidation” attribute:

 

internal sealed class CustomerMetadata

        {

 

            // Metadata classes are not meant to be instantiated.

            private CustomerMetadata()

            {

            }

 

            public string Address

            {

                get;

                set;

            }

 

            [CustomValidation(typeof(CustomerValidator), "IsCityValid")]

            public string City

            {

                get;

                set;

            }

 

That’s it. Here you can see RadGridView in action:

 

You can download the full source code of the example here.

Enjoy!

About the Author

Yavor Georgiev

Software Developer,
Telerik XAML Team

Comments

Comments are disabled in preview mode.