Walidacja MVC niższa/wyższa niż inne wartości

Jak najlepiej walidować model w MVC.Net gdzie chcę zaakceptować minimum / maksimum.

Nie pojedyncze wartości min / max dla pola. Ale oddzielne pola dla użytkownika, aby określić minimum / maksimum.

public class FinanceModel{
   public int MinimumCost {get;set;}
   public int MaximumCost {get;set;}
}

Więc muszę upewnić się, że MinimumCost jest zawsze mniejszy niż maksymalny koszt.

Author: Dani, 2013-09-02

5 answers

Możesz użyć niestandardowego atrybutu walidacji oto mój przykład z datami. Ale możesz go również używać z ints.

Po pierwsze, oto model:

public DateTime Beggining { get; set; }

    [IsDateAfterAttribute("Beggining", true, ErrorMessageResourceType = typeof(LocalizationHelper), ErrorMessageResourceName = "PeriodErrorMessage")]
    public DateTime End { get; set; }

A oto sam atrybut:

public sealed class IsDateAfterAttribute : ValidationAttribute, IClientValidatable
{
    private readonly string testedPropertyName;
    private readonly bool allowEqualDates;

    public IsDateAfterAttribute(string testedPropertyName, bool allowEqualDates = false)
    {
        this.testedPropertyName = testedPropertyName;
        this.allowEqualDates = allowEqualDates;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.testedPropertyName);
        if (propertyTestedInfo == null)
        {
            return new ValidationResult(string.Format("unknown property {0}", this.testedPropertyName));
        }

        var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);

        if (value == null || !(value is DateTime))
        {
            return ValidationResult.Success;
        }

        if (propertyTestedValue == null || !(propertyTestedValue is DateTime))
        {
            return ValidationResult.Success;
        }

        // Compare values
        if ((DateTime)value >= (DateTime)propertyTestedValue)
        {
            if (this.allowEqualDates && value == propertyTestedValue)
            {
                return ValidationResult.Success;
            }
            else if ((DateTime)value > (DateTime)propertyTestedValue)
            {
                return ValidationResult.Success;
            }
        }

        return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessageString,
            ValidationType = "isdateafter"
        };
        rule.ValidationParameters["propertytested"] = this.testedPropertyName;
        rule.ValidationParameters["allowequaldates"] = this.allowEqualDates;
        yield return rule;
    }
 22
Author: Boranas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-02 16:58:30

Istnieje pakiet NuGet o nazwie Foolproof , który zawiera te adnotacje dla Ciebie. To powiedziawszy-pisanie niestandardowego atrybutu jest zarówno dość łatwe, jak i Dobre praktyki.

Użycie Foolproof wyglądałoby następująco:

public class FinanceModel{
   public int MinimumCost {get;set;}

   [GreaterThan("MinimumCost")]
   public int MaximumCost {get;set;}
}
 27
Author: Matthew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-02 17:08:41

Dla walidacji po stronie klienta przy użyciu parametrów allowEqualDates i propertyTested (uzupełnienie odpowiedzi Boranas powyżej, ale zbyt długie na komentarz):

// definition for the isdateafter validation rule
if ($.validator && $.validator.unobtrusive) {
    $.validator.addMethod('isdateafter', function (value, element, params) {
        value = Date.parse(value);
        var otherDate = Date.parse($(params.compareTo).val());
        if (isNaN(value) || isNaN(otherDate))
            return true;
        return value > otherDate || (value == otherDate && params.allowEqualDates);
    });
    $.validator.unobtrusive.adapters.add('isdateafter', ['propertytested', 'allowequaldates'], function (options) {
        options.rules['isdateafter'] = {
            'allowEqualDates': options.params['allowequaldates'],
            'compareTo': '#' + options.params['propertytested']
        };
        options.messages['isdateafter'] = options.message;
    });
}

Więcej informacji: Dyskretna Walidacja, jQuery validation

 6
Author: Nicolas Galler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-16 10:55:03

W VB dla liczb całkowitych:

MODEL

<UtilController.IsIntegerGreatherOrEqualThan("PropertyNameNumberBegins", "PeriodErrorMessage")>
        Public Property PropertyNameNumberEnds As Nullable(Of Integer)

Walidacja

Public Class IsIntegerGreatherOrEqualThan
        Inherits ValidationAttribute

        Private otherPropertyName As String
        Private errorMessage As String

        Public Sub New(ByVal otherPropertyName As String, ByVal errorMessage As String)
            Me.otherPropertyName = otherPropertyName
            Me.errorMessage = errorMessage
        End Sub

        Protected Overrides Function IsValid(thisPropertyValue As Object, validationContext As ValidationContext) As ValidationResult

            Dim otherPropertyTestedInfo = validationContext.ObjectType.GetProperty(Me.otherPropertyName)

            If (otherPropertyTestedInfo Is Nothing) Then
                Return New ValidationResult(String.Format("unknown property {0}", Me.otherPropertyName))
            End If

            Dim otherPropertyTestedValue = otherPropertyTestedInfo.GetValue(validationContext.ObjectInstance, Nothing)

            If (thisPropertyValue Is Nothing) Then
                Return ValidationResult.Success
            End If

            ''  Compare values
            If (CType(thisPropertyValue, Integer) >= CType(otherPropertyTestedValue, Integer)) Then
                Return ValidationResult.Success
            End If

            ''  Wrong
            Return New ValidationResult(errorMessage)
        End Function
    End Class
 1
Author: Dani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-22 17:07:20

Dlaczego nie są używane range Validator. Składnia:

    [Range(typeof(int), "0", "100", ErrorMessage = "{0} can only be between {1} and {2}")]
    public int Percentage { get; set; }
 -8
Author: Khalid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-03 11:45:40