Telerik blogs

As you may recall from my previous blog post, we're revamping this application and bring it to the latest and greatest that is available in Silverlight today.  Coincidentally, Q2 2010 SP1 just came out today (check your accounts!) and I figured the best first place to start would be with something I removed previously- validation.

Since I redid the model for this application, I completely scrapped all of the previous validation because I knew I could now take advantage of using INotifyDataErrorInfo, which gives us a slightly more graceful way to handle asynchronous validation in our application.  I would explain all the details of what is involved with getting this setup, but my good friend Nedyalko already covered this a little while back, plus there is an excellent paper on Silverlight.Net.  So rest assured, there's resources out there for you. :)

First step was to add a method on my model that would validate a value.  Of course there are going to be more down the road, but starting with one is a great way to make sure something works before you implement it solution-wide.  One thing I know the HR admins mentioned is they hate getting duplicate applications / applicants, as this creates extra overhead when you get multiple versions of a resume for one person or similar issues.  Here is the simple check we're doing:

[Invoke]
public bool DoesEmailExist(string email)
{
    var doIExist = this.ObjectContext.Applicants.FirstOrDefault(x => x.Email == email);
    if (doIExist != null)
    {
        return false;
    }
    return true;
}

This is a bit self-explanatory, but what I do is check to see whether or not the email address (our tracking criteria) for an applicant being entered or edited exists already in the database.  If doIExist returns null, I know it wasn't found and we're okay, otherwise we have an issue. 

Next step is to add our custom validator, since the model is going to need to call this and use it to actually perform our check and return error information.  Per Nedyalko's advice, we've created a shared CustomValidator.shared.cs file in our .Web project so that it will populate out to both the MVVM and Code-Behind versions, with a few well placed #if statements to cover functionality that would be needed in the .Web project versus the Silverlight projects.  If there are errors we return them, otherwise we return the ValidationResult.Success value to show that this has passed all checks we provided:

    public class CustomValidator
    {
        public static ValidationResult DoesEmailExist(string email, ValidationContext validationContext)
        {
            ValidationResult errorResult = new ValidationResult("Email already exists in applicant database.",
                new string[] { validationContext.MemberName });
  
#if !SILVERLIGHT
            HRDomainService service = new HRDomainService();
  
            if (!service.DoesEmailExist(email))
            {
                return errorResult;
            }
#else
            HRDomainContext context = new HRDomainContext();
  
            InvokeOperation<bool> availability = context.DoesEmailExist(email);
  
            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;
        }
  
    }

 

Simple, right?  It gets better!  Now that we have a custom validator as well as a method that we call on the model, the last step is to add a line (yup, just one line) to our model metadata to utilize the custom validator:

[CustomValidation(typeof(CustomValidator), "DoesEmailExist")]
public string Email { get; set; }

 

And since my code was already set for validation, I make exactly zero changes to my XAML code in both versions of the app, and now I've got validation:

Email exists validation error

Now I can go about adding the rest of my metadata validations as well as custom cases like this.  Stay tuned for more next week, I've got a few more ideas up my sleeve for cool features to add, not to mention a pretty major UI overhaul!


About the Author

Evan Hutnick

works as a Developer Evangelist for Telerik specializing in Silverlight and WPF in addition to being a Microsoft MVP for Silverlight. After years as a development enthusiast in .Net technologies, he has been able to excel in XAML development helping to provide samples and expertise in these cutting edge technologies. You can find him on Twitter @EvanHutnick.

Comments

Comments are disabled in preview mode.