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:
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!
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.