状況
画面に開始日と終了日を入力するUIがあり、指定した範囲のデータを表示したい。
といったどこにでもある要求に対して、
検索機能はAPIを利用する
といったこれもまたどこにでもある要件。
ほしいもの
開始日と終了日が反対だったらAPIに渡る前のバリデーションで弾きたかったので、
- 開始日は入力必須
- 終了日が空の場合は終了
- 開始日と終了日が逆だったらエラー
みたいな要件を満たすバリデーションフィルターを作った。
作ったもの
結構ドタバタなコードなので、そのままだと堅いです。
あと開始日の入力必須は余計だったかも。
/// <summary>
/// 2つの日付が開始日と終了日が反対になっていないか検証する属性.
/// 終了日プロパティにつけて、PropertyNameに開始日プロパティ名を指定してください.
/// </summary>
public class DateTimeOppositeAttribute : ValidationAttribute
{
public string StartDatePropertyName { set; get; }
public DateTimeOppositeAttribute()
{
}
protected override ValidationResult IsValid( object value, ValidationContext validationContext)
{
// 開始日プロパティ取得
var startDateProperty = validationContext.ObjectInstance.GetType().GetProperty(StartDatePropertyName);
if (startDateProperty == null)
{
throw new ArgumentException( string.Format( "対象パラメータ名が見つかりません Name:{0}", StartDatePropertyName));
}
// 開始日プロパティの値取得
var startDateValue = startDateProperty.GetValue(validationContext.ObjectInstance, null );
if (startDateValue == null)
{
return new ValidationResult( "開始日を入力してください", new string [] { validationContext.MemberName });
}
var begin = startDateValue as DateTimeOffset?;
if (begin == null)
{
throw new ArgumentException( string.Format( "渡された型が違います Type:{0}", startDateValue.GetType().FullName));
}
// 終了日
if (value == null)
{
return ValidationResult.Success;
}
var end = value as DateTimeOffset?;
if (end == null)
{
throw new ArgumentException( string.Format( "渡された型が違います Type:{0}", value == null ? "NULL" : value.GetType().FullName));
}
if (!end.HasValue)
{
return ValidationResult.Success;
}
if (begin > end)
{
return new ValidationResult( "日付が反対です", new string [] { validationContext. MemberName });
}
return ValidationResult.Success;
}
}
自分が作る時に他フィールドとの連携記事が少なかったので、参考になれば幸いです。