ASP .NET MVC 3 аннотации данных больше, чем ниже, чем для DateTime и int - PullRequest
14 голосов
/ 07 мая 2011

Хотелось бы узнать, какой самый простой способ получить проверку «Больше, чем» и «Чем ниже» в форме ASP.NET MVC 3?

Я использую ненавязчивый JavaScript для проверки клиента. У меня есть два свойства DateTime (StartDate & EndDate), и мне нужна проверка, чтобы убедиться, что EndDate больше, чем StartDate. У меня есть другой похожий случай с другой формой, в которой у меня есть MinValue (int) и MaxValue (int).

Существует ли этот тип проверки по умолчанию? Или кто-то знает статью, в которой объясняется, как ее реализовать?

Ответы [ 5 ]

8 голосов
/ 13 сентября 2013

Вы можете просто сделать это с помощью пользовательской проверки.

[AttributeUsage(AttributeTargets.Property, AllowMultiple=true)]
    public class DateGreaterThanAttribute : ValidationAttribute
    {
        string otherPropertyName;

        public DateGreaterThanAttribute(string otherPropertyName, string errorMessage)
            : base(errorMessage)
        {
            this.otherPropertyName = otherPropertyName;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            ValidationResult validationResult = ValidationResult.Success;
            try
            {
                // Using reflection we can get a reference to the other date property, in this example the project start date
                var otherPropertyInfo = validationContext.ObjectType.GetProperty(this.otherPropertyName);
                // Let's check that otherProperty is of type DateTime as we expect it to be
                if (otherPropertyInfo.PropertyType.Equals(new DateTime().GetType()))
                {
                    DateTime toValidate = (DateTime)value;
                    DateTime referenceProperty = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
                    // if the end date is lower than the start date, than the validationResult will be set to false and return
                    // a properly formatted error message
                    if (toValidate.CompareTo(referenceProperty) < 1)
                    {
                        validationResult = new ValidationResult(ErrorMessageString);
                    }
                }
                else
                {
                    validationResult = new ValidationResult("An error occurred while validating the property. OtherProperty is not of type DateTime");
                }
            }
            catch (Exception ex)
            {
                // Do stuff, i.e. log the exception
                // Let it go through the upper levels, something bad happened
                throw ex;
            }

            return validationResult;
        }
}

и использовать ее в модели, например

 [DisplayName("Start date")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]        
    public DateTime StartDate { get; set; }

    [DisplayName("Estimated end date")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    [DateGreaterThan("StartDate", "End Date end date must not exceed start date")]
    public DateTime EndDate { get; set; }

Это хорошо работает при проверке на стороне сервера. Для проверки на стороне клиента вы можетенапишите метод наподобие GetClientValidationRules наподобие

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            //string errorMessage = this.FormatErrorMessage(metadata.DisplayName);
            string errorMessage = ErrorMessageString;

            // The value we set here are needed by the jQuery adapter
            ModelClientValidationRule dateGreaterThanRule = new ModelClientValidationRule();
            dateGreaterThanRule.ErrorMessage = errorMessage;
            dateGreaterThanRule.ValidationType = "dategreaterthan"; // This is the name the jQuery adapter will use
            //"otherpropertyname" is the name of the jQuery parameter for the adapter, must be LOWERCASE!
            dateGreaterThanRule.ValidationParameters.Add("otherpropertyname", otherPropertyName);

            yield return dateGreaterThanRule;
        }

Теперь просто в поле зрения

$.validator.addMethod("dategreaterthan", function (value, element, params) {

    return Date.parse(value) > Date.parse($(params).val());
});
$.validator.unobtrusive.adapters.add("dategreaterthan", ["otherpropertyname"], function (options) {
    options.rules["dategreaterthan"] = "#" + options.params.otherpropertyname;
    options.messages["dategreaterthan"] = options.message;
});

Более подробную информацию можно найти по этой ссылке

8 голосов
/ 21 сентября 2011

Может посмотреть на dataannotationsextensions , это делает Min / Max для int

Также обратите внимание на проверку правильности , в которую включено сравнение GreaterThan для числовых значений / даты и т. Д.

1 голос
/ 07 июня 2013

Я не знаю, является ли написание вашего собственного класса валидатора "самым простым" способом, но я так и сделал.

Использование:

<DataType(DataType.Date)>
Public Property StartDate() As DateTime


<DataType(DataType.Date)>
<DateGreaterThanEqual("StartDate", "end date must be after start date")>
Public Property EndDate() As DateTime

Класс:

<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
Public Class DateGreaterThanEqualAttribute
    Inherits ValidationAttribute

    Public Sub New(ByVal compareDate As String, ByVal errorMessage As String)
        MyBase.New(errorMessage)
        _compareDate = compareDate
    End Sub
    Public ReadOnly Property CompareDate() As String
        Get
            Return _compareDate
        End Get
    End Property
    Private ReadOnly _compareDate As String

    Protected Overrides Function IsValid(ByVal value As Object, ByVal context As ValidationContext) As ValidationResult
        If value Is Nothing Then
            ' no need to do or check anything
            Return Nothing
        End If
        ' find the other property we need to compare with using reflection
        Dim compareToValue = Nothing
        Dim propAsDate As Date
        Try
            compareToValue = context.ObjectType.GetProperty(CompareDate).GetValue(context.ObjectInstance, Nothing).ToString
            propAsDate = CDate(compareToValue)
        Catch
            Try
                Dim dp As String = CompareDate.Substring(CompareDate.LastIndexOf(".") + 1)
                compareToValue = context.ObjectType.GetProperty(dp).GetValue(context.ObjectInstance, Nothing).ToString
                propAsDate = CDate(compareToValue)
            Catch
                compareToValue = Nothing
            End Try
        End Try

        If compareToValue Is Nothing Then
            'date is not supplied or not valid
            Return Nothing
        End If

        If value < compareToValue Then
            Return New ValidationResult(FormatErrorMessage(context.DisplayName))
        End If

        Return Nothing
    End Function

End Class
0 голосов
/ 21 мая 2013

Посмотрите на ответ этой темы ,

Существует библиотека под названием MVC.ValidationToolkit.Хотя я не уверен, работает ли он в случае полей DateTime.

0 голосов
/ 01 июня 2012

Вы можете использовать атрибут DateGreaterThanEqual в вашей модели.Вот фрагмент кода, который я использовал для проверки двух полей в моей форме.

[DataType(DataType.Date)]
[DisplayName("From Date")]
public DateTime? StartDate { get; set; }

[DataType(DataType.Date)]
[DisplayName("To Date")]
[DateGreaterThanEqual("StartDate")]
public DateTime? EndDate { get; set; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...