簡體   English   中英

ASP MVC:自定義驗證屬性

[英]ASP MVC: Custom Validation Attribute

我正在嘗試編寫自己的自定義驗證屬性,但我遇到了一些問題。

我試圖寫的屬性是當用戶登錄時,密碼將與確認密碼進行比較。

namespace Data.Attributes
{
public class ComparePassword : ValidationAttribute
{
    public string PasswordToCompareWith { get; set; }

    public override bool IsValid(object value)
    {
        if (PasswordToCompareWith == (string)value)
        {
            return true;
        }
       return false;
    }
}

現在我的問題是當我試圖在模型文件中設置這樣的屬性時:

 [Required]
    [ComparePassword(PasswordToCompareWith=ConfirmPassword)]
    public string Password { get; set; }


    [Required]
    public string ConfirmPassword { get; set; }
   }

我收到以下錯誤:

錯誤1非靜態字段,方法或屬性'Project.Data.Models.GebruikerRegistreerModel.ConfirmPassword.get'需要對象引用

看來,VS是不接受confirmpasswordPasswordToCompareWith=ConfirmPassword一部分。

我究竟做錯了什么?

根據這個鏈接http://devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-1 ,現在MVC3中有一個特殊的驗證屬性:

public class RegisterModel
{
    // skipped

    [Required]
    [ValidatePasswordLength]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }                       

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation do not match.")]
    public string ConfirmPassword { get; set; }
}

CompareAttribute是一個新的,非常有用的驗證器,它實際上不是System.ComponentModel.DataAnnotations的一部分,但已被團隊添加到System.Web.Mvc DLL中。 雖然沒有特別好的命名(它唯一的比較是檢查相等性,所以也許E​​qualTo會更明顯),從使用中很容易看出這個驗證器檢查一個屬性的值等於另一個屬性的值。 您可以從代碼中看到,該屬性接受一個字符串屬性,該屬性是您要比較的另一個屬性的名稱。 這種驗證器的經典用法是我們在這里使用它:密碼確認。

很抱歉讓您失望,但使用數據注釋處理像您這樣的簡單案例可能會很痛苦。 你可以看一下這篇文章

我不知道為什么這是一個大問題,只需這樣做:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public class ComparePassword: ValidationAttribute
{
    public ComparePassword() 
        : base("Passwords must match.") { }

    protected override ValidationResult IsValid (object value, ValidationContext validationContext)
    {
        if (value == null) return new ValidationResult("A password is required.");

        // Make sure you change YourRegistrationModel to whatever  the actual name is
        if ((validationContext.ObjectType.Name != "YourRegistrationModel") 
             return new ValidationResult("This attribute is being used incorrectly.");
        if (((YourRegistrationModel)validationContext.ObjectInstance).ConfirmPassword != value.ToString())
            return new ValidationResult("Passwords must match.");

        return ValidationResult.Success;
    }
}

現在您需要做的就是將[ComparePassword]添加到您的密碼屬性中,無需通過......簡單而且相當干凈

FoolProof http://foolproof.codeplex.com/似乎是最好的解決方案。

public class SignUpViewModel
{
    [Required]
    public string Password { get; set; }

    [EqualTo("Password", ErrorMessage="Passwords do not match.")]
    public string RetypePassword { get; set; }
}

它比建議的PropertiesMustMatchAttribute更好,因為它為“RetypePassword”而不是像PropertiesMustMatchAttribute那樣添加了全局模型級別的驗證錯誤。

在你的情況下你需要一個STATIC方法:例子:

        public static ValidationResult ValidateFrequency( double frequency, ValidationContext context )
    {
        if( context == null )
        {
            return ( ValidationResult.Success );
        }
  }

僅作為一個例子:

 using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.Globalization;
 using System.Web.Mvc;
 using System.Web.Security;

 namespace GDNET.Web.Mvc.Validation
 {
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class ValidatePasswordLengthAttribute : ValidationAttribute, IClientValidatable
{
    private const string defaultErrorMessage = "'{0}' must be at least {1} characters long.";
    private readonly int minRequiredPasswordLength = Membership.Provider.MinRequiredPasswordLength;

    public ValidatePasswordLengthAttribute()
        : base(defaultErrorMessage)
    {
    }

    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, minRequiredPasswordLength);
    }

    public override bool IsValid(object value)
    {
        string valueAsString = value as string;
        return (valueAsString != null && valueAsString.Length >= minRequiredPasswordLength);
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        return new[]
        {
            new ModelClientValidationStringLengthRule(FormatErrorMessage(metadata.GetDisplayName()), minRequiredPasswordLength, int.MaxValue)
        };
    }
}
  }

來源: https//code.google.com/p/gdnetprojects/source/browse/trunk/Experiments/Common/GDNET.Web.Mvc/Validation/ValidatePasswordLengthAttribute.cs?r = 69

除非您執行一些相當蹩腳的反射代碼,否則不能將引用類型傳遞給屬性。

在這種情況下,我認為創建自定義模型綁定器會更好,然后在此時檢查密碼和ComparePassword。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM