Some types of validation are too specialized to be handled by an attribute. For
example, a login table should check the database for duplicate user names. For these,
add the DESDA.CustomValidationAttribute to invoke a method added to your Entity
class.
The PeterBlum.DES.DataAnnotations.CustomValidationAttribute is used for any server-side
only validation that you could not implement through any other ValidationAttribute.
This attribute supports validation on individual properties and on the overall Entity
class object (checking several properties together).
The validator’s logic is placed in a method in your Entity class (or another class
of your choice). The user interface layer doesn’t normally invoke it as there are
no “validator controls” associated with it. The BLD DataAccessObjects know to invoke
it and all other ValidationAttributes prior to saving.
In this example, the Category table does not allow duplicate CategoryName values.
The CategoryName property uses the DESDA.CustomValidationAttribute to invoke the
CheckForDuplicateCategoryNames() method on the Category class.
[EntityDAOType(typeof(CategoryDAO))]
[MetadataType(typeof(CategoryMetadata))]
public partial class Category
{
public ValidationResult CheckForDuplicateCategoryNames(
string newName, ValidationContext validationContext)
{
BaseDAOChangeEntityActionArgs vArgs = (BaseDAOChangeEntityActionArgs)validationContext.GetChangeEntityActionArgs();
ChangeEntityAction vAction = vArgs != null ? vArgs.Action : ChangeEntityAction.Update;
if ((vAction == ChangeEntityAction.Insert) || (vAction == ChangeEntityAction.Update))
{
Category vCategory = (Category)vArgs.Entity;
int vThisCategoryID = (vAction == ChangeEntityAction.Insert) ? -1 : vCategory.CategoryID;
NorthWindDataContext vDataContext = new NorthWindDataContext();
System.Data.Linq.Table<category> vTable = vDataContext.Categories;
if (vTable.FirstOrDefault<Category>(category =>
(category.CategoryName.Equal(newName, StringComparison.CurrentCultureIgnoreCase))
&& (category.CategoryID != vThisCategoryID)) != null)
{
DESDA.EntityValidationResult vResult = new DESDA.EntityValidationResult(
"This name already exists. Choose another.",
typeof(Category), "CategoryName", newName);
vResult.SummaryErrorMessage = "{LABEL} already exists. Choose another.";
return vResult;
}
}
return ValidationResult.Success;
}
}
public class CategoryMetadata
{
[DESDA.CustomValidation(MethodName="CheckForDuplicateCategoryNames")]
public object CategoryName { get; set; }
}
The error itself is communicated by the DESDA.EntityValidationResult object. This subclass
of System.ComponentModel.DataAnnotations.ValidationResult tracks more data that is useful to
the caller, such as two versions of the error message and the DataField which should reflect the error.
BLD's user interface will show this duplicate name error message next to the Category Name textbox,
just like the error messages from other ValidatorAttributes. If you used ValidationResult instead, the error message
could only appear in the ValidationSummary control.
The Source Code Browser shows completed DataAnnotations. The DESDA.CustomValidationAttribute
has been highlighted.
In the next topic, you'll learn about enabling
validators based on values of other columns.
Open the Source Code Browser (C# only)