web-dev-qa-db-ja.com

データアノテーションを使用したDateTime(日付と時間)の検証

私は次のコードを持っています:

        [DisplayName("58.Date and hour of birth")]
        [DataType(DataType.DateTime, ErrorMessage = "Please enter a valid date in the format dd/mm/yyyy hh:mm")]
        [Range(typeof(DateTime), "1/1/2011", "1/1/2016")]
        [RequiredToClose]
        public object V_58 { get; set; }

日付だけでなく、時刻(hh:mm形式)を強制的に含めたい。このコードは、2011年1月1日が時間を含んでいないため、有効ではない場合に有効と見なします。正しい形式を表現する方法についての手がかりはありますか? (dd/mm/yyyy hh:mm)

19
Marc

独自のValidationAttributeを記述して、プロパティをそれで飾ることができます。 IsValidメソッドを独自のロジックでオーバーライドします。

public class MyAwesomeDateValidation : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        DateTime dt;
        bool parsed = DateTime.TryParse((string)value, out dt);
        if(!parsed)
            return false;

        // eliminate other invalid values, etc
        // if contains valid hour for your business logic, etc

        return true;
    }
}

そして最後に、あなたの財産を飾ります:

[MyAwesomeDateValidation(ErrorMessage="You were born in another dimension")]
public object V_58 { get; set; }

注:プロパティの複数の検証属性には注意が必要です。これ以上カスタマイズしないと評価の順序を決定できないため、検証ロジックが重複していると、エラーメッセージに間違っていると正確に説明されていない可能性があります。プロパティを使用して(ええ、それは追加の文章です)

28
David Fox

最後に、カスタムのValidationAttributeで解決しました:

public class DateTimeValidation : RegularExpressionAttribute {
    public DateTimeValidation()
        : base(@"^((((31\/(0?[13578]|1[02]))|((29|30)\/(0?[1,3-9]|1[0-2])))\/(1[6-9]|[2-9]\d)?\d{2})|(29\/0?2\/(((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))|(0?[1-9]|1\d|2[0-8])\/((0?[1-9])|(1[0-2]))\/((1[6-9]|[2-9]\d)?\d{2})) (20|21|22|23|[0-1]?\d):[0-5]?\d$") {
        ErrorMessage = "Date must be in the format of : dd/mm/yyyy hh:mm";
    }
}
4
Marc

このソリューションでは、時間00.00を入力できませんが、別の値で機能します。

public class TimeRequiredAttribute : ValidationAttribute
{
    protected override IsValid(object value)
    {
        DateTime result;
        bool parsed = DateTime.TryParse((string)value, out result);
        if(!parsed && DateTime.MinValue.TimeOfDay == result.TimeOfDay)
        {
           return false;
        }
        return true;
    }
}

しかし、それは文字列プロパティでのみ機能します。

0
Alex Shkor

文字列で日付を渡すだけの場合、それは12:00 AMと見なされます。文字列内で時間を渡したい場合は、「06/06/2011 7:00 PM」構文を使用します。

他の回避策は、文字列をそのままにして、DateTimeに変換してから、必要に応じてAddHoursおよび/またはAddMinutesをDateTimeオブジェクトに変換することです。

0
User_1983