IValidateableObject を使用します。オブジェクト クラスがこのインターフェイスを実装している場合、オーバーライド可能な validate メソッドが公開され、必要な場合にのみ object.validate でこの検証を呼び出すことができます。true または false を返します。その検証関数内で、オブジェクト プロパティをループし、カスタム bunisness ロジックに基づいて必要な列を IDataerrorInfo に追加できます。これを行うには、モデル/オブジェクト クラスに継承される Validationbase クラスを作成します。
モデル/オブジェクト クラスに継承できる検証基本クラスの例を次に示します。
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.ComponentModel;
using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
public class ValidationBase : IValidatableObject, IDataErrorInfo, INotifyPropertyChanged
{
#region "DECLARATIONS"
protected Dictionary<string, string> _propertyErrors = new Dictionary<string, string>();
protected List<ValidationResult> _validationResults = new List<ValidationResult>();
public bool HasErrors {
get { return (_propertyErrors.Count + _validationResults.Count) > 0; }
}
#endregion
#region "IValidatableObject IMPLEMENTATION"
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
return null;
}
#endregion
#region "iDataError OBJECTS"
//Returns an error message
//In this case it is a general message, which is
//returned if the list contains elements of errors
public string Error {
get {
if (_propertyErrors.Count > 0) {
return "Object data is invalid";
} else {
return null;
}
}
}
public string this[string columnName] {
get {
if (_propertyErrors.ContainsKey(columnName)) {
return _propertyErrors[columnName].ToString();
} else {
return null;
}
}
}
#endregion
#region "IDataError FUNCTIONS"
//Adds an error to the collection, if not already present
//with the same key
protected void AddError(string columnName, string msg)
{
if (!_propertyErrors.ContainsKey(columnName)) {
_propertyErrors.Add(columnName, msg);
OnPropertyChanged(columnName);
}
}
//Removes an error from the collection, if present
protected void RemoveError(string columnName)
{
if (_propertyErrors.ContainsKey(columnName)) {
_propertyErrors.Remove(columnName);
OnPropertyChanged(columnName);
}
}
public void ClearErrors()
{
_propertyErrors.Clear();
}
#endregion
#region "INotifyPropertyChanged IMPLEMENTATION"
public event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged;
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
モデルとしてエンティティ フレームワークを使用している場合、オブジェクトが db.SaveChanges 経由で保存される前に、validate メソッドが呼び出されると思います。
モデルに検証ベースを実装する方法は次のとおりです。
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public partial class vendor : ValidationBase
{
#region "PROPERTIES"
public bool HasChanges { get; set; }
#endregion
#region "VALIDATION FUNCTIONS"
public override IEnumerable<ComponentModel.DataAnnotations.ValidationResult> Validate(ComponentModel.DataAnnotations.ValidationContext validationContext)
{
return base.Validate(validationContext);
PropertyValitaion(true);
}
public void PropertyValitaion(bool bAllProperties, string sProperty = "")
{
//your property specific logic goes here
}
#endregion
}