web-dev-qa-db-ja.com

MVC検証が他の値より低い/高い

最小/最大を受け入れたいMVC.Netのモデルを検証する最良の方法はどのようになりますか。

フィールドの個々の最小/最大値ではありません。ただし、ユーザーが最小/最大を指定するためのフィールドを分けてください。

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

そのため、MinimumCostが常にMaximum cost未満になるようにする必要があります。

25
Ben Ford

ここでカスタム検証属性を使用できます。これは、日付を使用した私の例です。ただし、intでも使用できます。

まず、モデルは次のとおりです。

public DateTime Beggining { get; set; }

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

そして、これが属性そのものです:

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;
    }
23
Boranas

これらの注釈を提供する Foolproof というNuGetパッケージがあります。そうは言っても、カスタム属性の作成は非常に簡単であり、優れたプラクティスです。

Foolproofの使用は次のようになります。

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

   [GreaterThan("MinimumCost")]
   public int MaximumCost {get;set;}
}
28
Matthew

AllowEqualDatesおよびpropertyTestedパラメーターを使用したクライアント側の検証(上記のBoranasの回答を補完しますが、コメントするには長すぎます):

// 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;
    });
}

詳細: 控えめな検証jquery検証

6
Nicolas Galler

In VB整数の場合:

[〜#〜] model [〜#〜]

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

[〜#〜] validation [〜#〜]

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
Dani