UI に関連付けられていないオブジェクトに対して検証を実行しようとしています。たとえば、次の 3 つのクラスがあります。
public class XDeftable {
[ObjectCollectionValidator(typeof(XSchedGroup))]
public List<XSchedGroup> SCHED_GROUP { get; set; }
}
[IdentifyingProperty("TABLE_NAME")]
public class XSchedGroup {
[ObjectCollectionValidator(typeof(XJob))]
public List<XJob> JOB { get; set; }
[Required]
public string TABLE_NAME { get; set; }
}
[IdentifyingProperty("JOBNAME")]
public class XJob : ICalendar {
[Required]
public string JOBNAME { get; set; }
[Range(-62, 62)]
public string SHIFTNUM { get; set; }
[ObjectCollectionValidator(typeof(XTagNames))]
public List<XTagNames> TAG_NAMES { get; set; }
}
XDeftable -> XSchedGroup -> XJob -> XTagNames
オブジェクトが検証に失敗すると、期待どおりに動作しますが、ValidationResult のKeyとMessageを単純に検査すると、 「JOBNAME | フィールドが必要です」のような結果になります。
これの問題は、1 つのスケジューリング グループに何百ものジョブがある可能性があることを考えると、どの特定のジョブが失敗したかがわからないため、検証が役に立たないことです。検証と C# に関して見つけられるすべてのドキュメントを検索しましたが、それ以上のデータを取得する方法は見つかりませんでした。クラスのどのプロパティがクラスの特定のインスタンスを識別するかをタグ付けできるように、IdentifyingProperty 属性を作成しました。この Git Repo に基づいてモックアップした以前のカスタム検証ソリューションがありました: https://github.com/reustmd/DataAnnotationsValidatorRecursive/tree/master/DataAnnotationsValidator/DataAnnotationsValidator。問題なく動作しましたが、より堅牢なものに交換したかったのです。
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class IdentifyingProperty : Attribute {
public string Name { get; set; }
public IdentifyingProperty(string name) {
this.Name = name;
}
}
これまでのところ、次のことを思いつくことができました。
public ValidationResults Validate(XDeftable deftable) {
var results = new ObjectValidator(typeof(XDeftable)).Validate(deftable);
var detailedResults = new ValidationResults();
foreach (var item in results) {
var targetType = item.Target.GetType();
var identProp = targetType.GetCustomAttribute<IdentifyingProperty>();
if (identProp != null) {
var pi = targetType.GetProperty(identProp.Name);
var newKey = String.Format("{0}[{1}].{2}", targetType.Name, pi.GetValue(item.Target).ToString(), item.Key);
detailedResults.AddResult(new ValidationResult(item.Message, item.Target, newKey, item.Tag, item.Validator));
}
else {
detailedResults.AddResult(item);
}
}
return detailedResults;
}
これにより、少なくとも「XJob[JOBNAME].SHIFTNUM | The field SHIFTNUM must be between -62 and 62.」が返されます。XSchedGroup[TABLE_NAME].XJob[JOBNAME].SHIFTNUMのようなコンテナーのチェーンをたどる結果を取得する方法があれば、私はまだそれを望んでいます。