ASP MVC: пользовательский атрибут проверки - PullRequest
6 голосов
/ 27 апреля 2010

Я пытаюсь написать свой собственный атрибут пользовательской проверки, но у меня возникли некоторые проблемы.

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

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 не принимает confirmpassword в части PasswordToCompareWith=ConfirmPassword.

Что я делаю не так?

Ответы [ 7 ]

18 голосов
/ 23 мая 2011

По этой ссылке 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 от команды. в то время как не особенно хорошо назван (единственный сравнение это делает, чтобы проверить равенство, так что, возможно, EqualTo будет более очевидно), это легко увидеть из использование, которое проверяет этот валидатор что стоимость одного свойства равна стоимость другого имущества. Вы можете из кода видно, что атрибут принимает строковое свойство, которое название другого свойства, которое ты сравниваешь. Классическое использование этого типа валидатора это то, что мы Используем его здесь: пароль подтверждение.

4 голосов
/ 27 апреля 2010

Извините, что разочаровал вас, но работа с таким простым делом, как у вас, с использованием аннотаций данных может быть трудной. Вы можете взглянуть на этот пост .

1 голос
/ 15 июля 2013

Я не знаю, почему это так важно, просто сделайте это:

[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] к свойству пароля, ничего не передать ... просто и довольно чисто

1 голос
/ 21 мая 2011

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.

0 голосов
/ 07 октября 2014

просто в качестве примера:

 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

0 голосов
/ 09 мая 2014

вам нужен метод STATIC в вашем случае: ПРИМЕР:

        public static ValidationResult ValidateFrequency( double frequency, ValidationContext context )
    {
        if( context == null )
        {
            return ( ValidationResult.Success );
        }
  }
0 голосов
/ 27 апреля 2010

Вы не можете передать ссылочный тип атрибуту, если не сделаете какой-то довольно слабый код отражения.

В этой ситуации я бы подумал, что лучше создать пользовательский механизм связывания модели, а затем проверить пароль и ComparePassword на этом этапе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...