Проверка правильности изменения свойства в ASP.NET MVC 3 по условию

Это моя модель:

[RegularExpression(@"^08[589][0-9]{8}$", ErrorMessage = "Invalid Number!")]
public string Phone { get; set; }

[ForeignKey]
public long PhoneType { get; set; } // 1-CellPhone , 2-Phone

Вот думаю поменять RegularExpression Проверка по изменению PhoneType если я хочу сказать более конкретно:

если пользователь выбирает CellPhone от DropDownList проверка будет

[RegularExpression(@"^08[589][0-9]{8}$", ErrorMessage = "Invalid Number!")] 

и если выбрать Phone проверка будет

 [RegularExpression("^[1-9][0-9]{9}$", ErrorMessage = "Invalid Number!")]

Что вы предлагаете?

1 ответ

Решение

Вы можете написать собственный атрибут проверки:

public class PhoneAttribute : ValidationAttribute
{
    private readonly string _phoneTypeProperty;
    public PhoneAttribute(string phoneTyperoperty)
    {
        _phoneTypeProperty = phoneTyperoperty;
    }

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

        var phone = Convert.ToString(value, CultureInfo.CurrentCulture);
        if (string.IsNullOrEmpty(phone))
        {
            return null;
        }

        var phoneType = (long)property.GetValue(validationContext.ObjectInstance, null);
        Regex regex = null;
        if (phoneType == 1)
        {
            regex = new Regex(@"^08[589][0-9]{8}$");
        }
        else if (phoneType == 2)
        {
            regex = new Regex("^[1-9][0-9]{9}$");
        }
        else
        {
            return new ValidationResult(string.Format("Unknown phone type: {0}", phoneType));
        }

        var match = regex.Match(phone);
        if (match.Success && match.Index == 0 && match.Length == phone.Length)
        {
            return null;
        }

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

а затем украсьте свойство модели представления этим атрибутом:

public class MyViewModel
{
    [Phone("PhoneType", ErrorMessage = "Invalid Number!")]
    public string Phone { get; set; }

    public long PhoneType { get; set; }
}

Еще одна возможность (и я бы ее более чем настоятельно рекомендовал), если вы хотите упростить свою жизнь с помощью валидации, - это использовать FluentValidation.NET. Просто взгляните на то, как проще определить правила проверки, а не писать множество строк кода, и больше не сможете понять, какая часть является сантехнической, а какая - реальной проверкой. С FluentValidation.NET нет сантехники. Вы свободно выражаете свои требования к валидации:

public class MyViewModelValidator : AbstractValidator<MyViewModel>
{
    public MyViewModelValidator()
    {
        RuleFor(x => x.Phone)
            .Matches(@"^08[589][0-9]{8}$").When(x => x.PhoneType == 1)
            .Matches("^[1-9][0-9]{9}$").When(x => x.PhoneType == 2);
    }
}

Просто сравните этот валидатор с предыдущим.

Другие вопросы по тегам