-
Notifications
You must be signed in to change notification settings - Fork 0
Data Validation
Validating objects is a common and important task in applications and so SoftFluent CodeModeler offers advanced validation capabilities based on the standard .Net validation features.
In fact, in addition to ensuring that pushed data is not ill-formatted, validating data based on a business rule is a common need in business applications, therefore it's a core part of the business logic. As exposed throughout this documentation, all the business logic should be held in the Business Object Model (BOM), consequently, validation capabilities should also.
Furthermore, lots of user interface (UI) components such as data grids, or simple controls have validation capabilities. For instance, when one of those UI controls are data bound to an object supporting data validation, they will automatically display the validation result. To enable this behavior, objects must implement:
-
the validation capability through a Validate method,
-
the standard .NET IDataErrorInfo interface, which provides the functionality to offer custom error information that a user interface can bind to.
Consequently, all CodeModeler-generated classes implement steps one and two, providing by default, a full data validation capability to the developer.
To support step 1, the following methods are generated:
-
public void Validate()
-
public virtual string Validate(CultureInfo culture)
-
protected virtual void ValidateMember(CultureInfo culture, string memberName, IList<CodeModelerValidationException> results)
The ValidateMember method is protected, to call it you should use the static ValidateMember method of the CodeModeler.Runtime.CodeModelerPersistence class : public static IList<CodeModelerValidationException> ValidateMember(CultureInfo culture, IValidator validator, string memberName)
In the Save method of an entity, the Validate method is automatically called so you don't have to handle the validation.
You can also directly use the IMemberValidator interface. In fact, that's what the Validate method contained in the CodeModelerPersistence class does.
Implementing the standard .NET IDataErrorInfo interface adds the following methods to the generated entity class:
-
string System.ComponentModel.IDataErrorInfo.Error
-
string System.ComponentModel.IDataErrorInfo.this[string columnName]
On top of those basic mechanisms, when modeling your application, you can add custom validation rules to an entity. Please refer to the Data Validation Example below for more on how to implement those custom validation rules.
Finally, it's important to note that by default all entities call the validate method before saving.
This example demonstrates how a developer can validate an Employee entity with three validation rules:
-
a String validation rule for the Name property,
-
a RegularExpression validation rule for the EMail property,
-
a Compare validation rule for the Age property.
In the BOM, in the Employee entity class, a ValidateMember method is generated. This method handles validation for the Name, EMail and Age properties:
protected virtual void ValidateMember(CultureInfo culture, string memberName, IList<CodeModelerValidationException> results)
{
if ((memberName == "Name") || (memberName == null))
{
ValueValidator.Validate(culture, "Name", results, NameValidator0, this.Name);
}
if ((memberName == "EMail") || (memberName == null))
{
ValueValidator.Validate(culture, "EMail", results, EMailValidator0, this.EMail);
}
if ((memberName == "Age") || (memberName == null))
{
ValueValidator.Validate(culture, "Age", results, AgeValidator0, this.Age);
}
}
Developers can then validate the Employee entity by:
-
using the Employee Validate method
-
using the CodeModelerPersistence.Validate method.
Note that with the CodeModelerPersistence.Validate method, developers get list of raised exceptions, making it possible to handle each exception individually.
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using CodeModeler.Runtime;
using HowTo;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var employee = new Employee();
employee.Name = "Pat_Clark";
employee.EMail = "pat@hotmail";
employee.Age = 200;
var exception = employee.Validate(CultureInfo.CurrentCulture);
if (exception != null)
{
Console.WriteLine("=====================================================");
Console.WriteLine("Use of the Employee.Validate method");
Console.WriteLine("=====================================================");
Console.WriteLine(exception);
}
var validator = (IValidator)employee;
string memberName = null;
IList<CodeModelerValidationException> exceptions = CodeModelerPersistence.ValidateMember(CultureInfo.CurrentCulture, validator, memberName);
Console.WriteLine("=====================================================");
Console.WriteLine("Use of the CodeModelerPersistence.ValidateMember method");
Console.WriteLine("=====================================================");
foreach (CodeModelerValidationException ex in exceptions)
{
Console.WriteLine(ex.Message);
}
var otherValidator = (ISummaryValidator)employee;
string errors = CodeModelerPersistence.Validate(CultureInfo.CurrentCulture, otherValidator, "|");
Console.WriteLine("=====================================================");
Console.WriteLine("Use of the CodeModelerPersistence.Validate method");
Console.WriteLine("=====================================================");
Console.WriteLine(errors);
Console.ReadLine();
}
}
}
Using one way or the other returns the same result, however the second way can be useful if the validation results should be formatted and displayed to the user. This is a console output:
CM1704: 'Pat_Clark' value for 'Name' contains one or more of the following invalid characters '_'.
CM1707: 'pat@hotmail' value for 'EMail' does not match the regular expression '[\w]+@[\w]+\.[\w]+'.
CM1708: '200' value for 'Age' failed comparison with '100' for operator 'LessThanEqual'.
Validation messages can be localized, check-out the Localizing Static Resources for more information on that topic.
- Introduction
- Architect Guide
- Concepts
- Using Visual Studio
- Overview
- Creating a CodeModeler Project
- Visual Environment
- Project Hierarchy
- Design Surface
- Customizing Design Surfaces
- Ribbon Bar
- Property Grid
- Member Format Expressions
- Model Grid
- Method Editor
- View Editor
- Instance Editor and Grid
- Resources Editor
- Inferred Model Viewer
- Building
- Project Physical Layout
- Source Control Support
- Generating
- Aspect Oriented Design (AOD)
- Developer Guide
- The Business Object Model (BOM)
- CodeModeler Query Language (CMQL)
- Starting Guide - Tutorial
- Upgrade From CFE