Ответ 1
В ASP.NET MVC 3 Framework есть атрибут CompareAttribute, который делает это. Если вы используете ASP.NET MVC 2 и таргетинг .NET 4.0, вы можете посмотреть реализацию в исходном коде ASP.NET MVC 3.
Как я могу написать специальный параметр ValidationAttribute, который сравнивает два поля? Это общий сценарий "ввести пароль", "подтвердить пароль". Я должен быть уверен, что два поля равны, и чтобы все было согласовано, я хочу реализовать проверку с помощью DataAnnotations.
Итак, в псевдокоде я ищу способ реализовать что-то вроде следующего:
public class SignUpModel
{
[Required]
[Display(Name = "Password")]
public string Password { get; set; }
[Required]
[Display(Name = "Re-type Password")]
[Compare(CompareField = Password, ErrorMessage = "Passwords do not match")]
public string PasswordConfirm { get; set; }
}
public class CompareAttribute : ValidationAttribute
{
public CompareAttribute(object propertyToCompare)
{
// ??
}
public override bool IsValid(object value)
{
// ??
}
}
Итак, вопрос в том, как мне закодировать [Compare] ValidationAttribute?
В ASP.NET MVC 3 Framework есть атрибут CompareAttribute, который делает это. Если вы используете ASP.NET MVC 2 и таргетинг .NET 4.0, вы можете посмотреть реализацию в исходном коде ASP.NET MVC 3.
Убедитесь, что ваш проект ссылается на system.web.mvc v3.xxxxx.
Тогда ваш код должен выглядеть примерно так:
using System.Web.Mvc;
. , , .
[Required(ErrorMessage = "This field is required.")]
public string NewPassword { get; set; }
[Required(ErrorMessage = "This field is required.")]
[Compare(nameof(NewPassword), ErrorMessage = "Passwords don't match.")]
public string RepeatPassword { get; set; }
Это более длинная версия ответа Дарина:
public class CustomAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value.GetType() == typeof(Foo))
{
Foo bar = (Foo)value;
//compare the properties and return the result
}
throw new InvalidOperationException("This attribute is only valid for Foo objects");
}
}
и использование:
[MetadataType(typeof(FooMD))]
public partial class Foo
{
... functions ...
}
[Custom]
public class FooMD
{
... other data annotations ...
}
Ошибка будет отображаться в @Html.ValidationSummary(false)
У вас может быть специальный атрибут проверки и применить его к модели, а не по отдельным свойствам. Здесь пример, на который вы можете взглянуть.
Если вы, ребята, используете MVC 4, попробуйте этот код.. он решит вашу ошибку.
сделайте один метадатчик, чем в свойствах comfirmemail класса imiment. проверьте приведенный ниже код для получения более подробной информации.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using StringlenghtMVC.Comman;
using System.Web.Mvc;
using System.Collections;
[MetadataType(typeof(EmployeeMetaData))] //here we call metadeta class
public partial class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public Nullable<int> Age { get; set; }
public string Gender { get; set; }
public Nullable<System.DateTime> HireDate { get; set; }
//[CompareAttribute("Email")]
public string ConfirmEmail { get; set; }
}
public class EmployeeMetaData
{
[StringLength(10, MinimumLength = 5)]
[Required]
//[RegularExpression(@"(([A-za-Z]+[\s]{1}[A-za-z]+))$", ErrorMessage = "Please enter Valid Name")]
public string Name { get; set; }
[Range(1, 100)]
public int Age { get; set; }
[CurrentDate]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime HireDate { get; set; }
//[RegularExpression(@"^[\w-\._\%][email protected](?:[\w]{2,6}$")]
public string Email { get; set; }
[System.Web.Mvc.CompareAttribute("Email")]
public string ConfirmEmail { get; set; }
}
Для будущих людей, рассматривающих эту проблему, я пытался написать атрибут проверки, который оценивал бы регулярное выражение, если свойство объекта было определенным значением. В моем случае, если адрес был адресом доставки, я не хотел, чтобы PO Boxes был включен, так что это то, что я придумал:
Использование
[Required]
public EAddressType addressType { get; set; } //Evaluate Validation attribute against this
[EvaluateRegexIfPropEqualsValue(Constants.NOT_PO_BOX_REGEX, "addressType", EAddressType.Shipping, ErrorMessage = "Unable to ship to PO Boxes or APO addresses")]
public String addressLine1 { get; set; }
И вот код для атрибута проверки:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class EvaluateRegexIfPropEqualsValue : ValidationAttribute
{
Regex _regex;
string _prop;
object _targetValue;
public EvaluateRegexIfPropEqualsValue(string regex, string prop, object value)
{
this._regex = new Regex(regex);
this._prop = prop;
this._targetValue = value;
}
bool PropertyContainsValue(Object obj)
{
var propertyInfo = obj.GetType().GetProperty(this._prop);
return (propertyInfo != null && this._targetValue.Equals(propertyInfo.GetValue(obj, null)));
}
protected override ValidationResult IsValid(object value, ValidationContext obj)
{
if (this.PropertyContainsValue(obj.ObjectInstance) && value != null && !this._regex.IsMatch(value.ToString()))
{
return new ValidationResult(this.ErrorMessage);
}
return ValidationResult.Success;
}
}