Up Validation code samples
DevForce 2010 Resource Center » Code samples » Validation code samples » Code sample: Validation Lab (Desktop)

Code sample: Validation Lab (Desktop)

Last modified on August 15, 2012 17:22

This sample illustrates a variety of DevForce Validation principles and techniques, both simple and advanced, through the medium of automated tests.


Overview

This Validation Lab explains several DevForce validation concepts and techniques using automated tests run within the Microsoft Unit Test framework. Small tests highlight small points and nuances and they encourage you to extend your explorations by adding new tests. Oh … we also believe testing is good practice and testing with DevForce is easy when you know how. We hope labs like this one encourage you to write tests for your own application.

To run the lab, open it in Visual Studio and press F5, [Ctrl-R, A], or [Ctrl-R, Ctrl-A]. You should see output in the "Test Results" window that looks like this (once you group the results by "Class Name"):

DesktopValidationLab.png

The lab includes examples covering many points including:

  • Validating entities in cache only (When_validating_Customer_in_cache)
  • Exercise of generated DevForce verifiers (StringLengthVerifier for Customer.CompanyName)
  • Validating entities on the client during a save operation (OnSaveValidator, When_client_saves)
  • Custom PropertyValueVerifier (NotEmptyGuidVerifier, GoldilocksVerifier, UniqueVerifier)
  • Custom verifier attribute (UniqueAttribute)
  • Adding a validation attribute to an entity’s Metadata buddy class (Customer, OrderDetail)
  • Use of a discovered VerifierProvider (ModelVerifierProvider) to add verifiers to a VerifierEngine automatically without modifying the entity classes (a POCO friendly approach)
  • Add a verifier to a VerifierEngine on the fly (When_using_GoldilocksVerifier)
  • Custom resources for validation error message modification (CustomResources.resx); TODO: satellite versions of those resources in another language.
  • Replace a DevForce validation error message template in a custom resource (“VerifierRequired” in CustomResources.resx)
  • Validation error message localization facility made available to developers (DevForceResourceManagerEmulator).
  • Exercise of the .NET INotifyDataErrorInfo interface, implemented by DevForce entities, for exposing validation errors to the UI (testCustIndei test property in When_validating_Customer_in_cache)
  • Property validation is performed when entity is detached or deleted but not when new-and-not-yet-attached (When_validating_Customer_in_cache)

Most test are run offline

Validations can be performed client-side, server-side and most often on both sides. Validation logic is typically the same no matter where it is executed
(although that is not a technology requirement).

It is often best to write tests that are unencumbered by external concerns. Validation tests tend to fall in this camp. A validation test shouldn't be at risk of failure because the server or the database is unreachable in the test environment.

Therefore, many of the test class in the lab use a disconnected EntityManager that makes no attempt to reach a server or the database.

The manager is still needed because it provides the context within which entities are validated. The test does_not_validate_when_new_Customer_is_unattached in When_validating_Customer_in_cache shows that automatic property validation doesn't happen until an entity has been attached to an EntityManager. Property validation occurs only when an entity is associated with an EntityManager which can provide a VerifierEngine to perform the validation. But that manager can be disconnected and still deliver a working VerifierEngine.

The UniqueVerifier

There is one custom verifier, the UniqueVerifier that can only be fully tested with a connected EntityManager. This verifier checks the database to see if a proposed property value is unique. Accordingly, the When_Customer_name_must_be_unique and When_OrderDetail_quantity_must_be_unique test classes use an EntityManager that connects to the database.

We hesitated to include the UniqueVerifier in this lab. Validation logic that depends upon service calls shouldn’t be done in a verifier at all, neither on client nor server. Yes, it is often a good idea to test for uniqueness on the client as when checking if a candidate "UserName" is available. Such a check can catch a duplicate UserName early and pop a dialog to give the user an opportunity to pick a different name. However, such a complex user experience is not typical of a routine value validation. It is really a different kind of application logic than one finds in a simple validation.

Unlike normal validations, the uniqueness check is always provisional, never definitive. If a quantity is out of the acceptable range now, it is always out of range. But uniqueness cannot be verified locally and you can't be sure that another user won't sneak in a duplicate after you've looked at the database. The only sure way to know if the value is unique is to submit it to the database in a transaction and let the database’s uniqueness constraint do the work.

Another reason to be wary of this verifier is that it makes a synchronous call to the server thus blocking the UI while waiting for the server response. It wouldn't work at all in Silverlight. While you could devise an asynchronous alternative, you would be ensnared in more user experience issues, trying to figure out how to hold the user's attention until the server replied. Validation wasn't designed for these kinds of scenarios.  

If it's such a bad idea, why is it in the lab?  It's here because customers want to know how to write such validations anyway. We wouldn't want to you to think that DevForce can't do it. 

Created by DevForce on September 07, 2011 17:45

This wiki is licensed under a Creative Commons 2.0 license. XWiki Enterprise 3.2 - Documentation. Copyright © 2015 IdeaBlade