mvc3 проверяет правильность ввода «не равно» - PullRequest
14 голосов
/ 21 апреля 2011

Мои формы содержат входные данные со вспомогательным текстом по умолчанию, который указывает пользователю, что вводить (вместо использования меток). Это усложняет проверку, потому что входное значение никогда не равно нулю.

Как я могу расширить ненавязчивую проверку, чтобы справиться с этим? Форма не должна быть действительной, если ввод имени равен «Пожалуйста, введите ваше имя ...»

Я начал читать сообщение в блоге Брэда Уилсона об адаптерах проверки, но я не уверен, что это правильный путь? Мне нужно иметь возможность проверять на различные значения по умолчанию в зависимости от поля.

Спасибо

Ответы [ 6 ]

32 голосов
/ 21 апреля 2011

Вот пример, иллюстрирующий, как вы можете приступить к реализации пользовательского атрибута проверки:

public class NotEqualAttribute : ValidationAttribute, IClientValidatable
{
    public string OtherProperty { get; private set; }
    public NotEqualAttribute(string otherProperty)
    {
        OtherProperty = otherProperty;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var property = validationContext.ObjectType.GetProperty(OtherProperty);
        if (property == null)
        {
            return new ValidationResult(
                string.Format(
                    CultureInfo.CurrentCulture, 
                    "{0} is unknown property", 
                    OtherProperty
                )
            );
        }
        var otherValue = property.GetValue(validationContext.ObjectInstance, null);
        if (object.Equals(value, otherValue))
        {
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
        return null;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = ErrorMessage,
            ValidationType = "notequalto",
        };
        rule.ValidationParameters["other"] = OtherProperty;
        yield return rule;
    }
}

и затем на модели:

public class MyViewModel
{
    public string Prop1 { get; set; }

    [NotEqual("Prop1", ErrorMessage = "should be different than Prop1")]
    public string Prop2 { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            Prop1 = "foo",
            Prop2 = "foo"
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

и просмотр:

@model MyViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    jQuery.validator.unobtrusive.adapters.add(
        'notequalto', ['other'], function (options) {
            options.rules['notEqualTo'] = '#' + options.params.other;
            if (options.message) {
                options.messages['notEqualTo'] = options.message;
            }
    });

    jQuery.validator.addMethod('notEqualTo', function(value, element, param) {
        return this.optional(element) || value != $(param).val();
    }, '');
</script>

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.Prop1)
        @Html.EditorFor(x => x.Prop1)
        @Html.ValidationMessageFor(x => x.Prop1)
    </div>
    <div>
        @Html.LabelFor(x => x.Prop2)
        @Html.EditorFor(x => x.Prop2)
        @Html.ValidationMessageFor(x => x.Prop2)
    </div>
    <input type="submit" value="OK" />
}
3 голосов
/ 21 апреля 2011

Да, это правильный путь.Вы должны реализовать свой собственный атрибут и реализовать IClientValidatable.

. В качестве скрытого поля формы можно также изначально установить обязательное логическое значение false.Когда пользователь изменит текстовое поле, установите для него значение true.

0 голосов
/ 18 января 2016

Чтобы немного улучшить ответ @Darin Dimitrov, если вы хотите добавить сообщения из ресурсов с помощью ErrorMessageResourceName and ErrorMessageResourceType, просто добавьте это к сообщению об ошибке ErrorMessage = ErrorMessage ?? ErrorMessageString

ErrorMessageString будет выглядетьдля локализованной версии сообщения об ошибке, установленного в модели с использованием этих параметров (ErrorMessageResourceName и ErrorMessageResourceType)

0 голосов
/ 18 июля 2014

Прошло немного времени, так как ваш вопрос был задан, но если вам все еще нравятся аннотации данных, эту проблему можно легко решить, используя эту библиотеку :

[Required]
[AssertThat("FieldA != 'some text'")]
public string FieldA { get; set; }

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

[AssertThat("FieldA != FieldB")]

... и когда случай сравниваемых строк не имеет значения:

[AssertThat("CompareOrdinalIgnoreCase(FieldA, FieldB) != 0")]
0 голосов
/ 21 апреля 2011

Вы можете заставить свой ViewModel реализовать IValidatableObject и при реализации метода Validate (из IValidatableObject) добавить некоторую логику для проверки значений свойств, например,

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
        var results = new List<ValidationResult>();

        if (Name == "Please enter your name...") 
            results.Add(new ValidationResult("You must enter a name");

        ...
        Enter other validation here
        ...     

        return results;
    }

Теперь, когда Model.IsValid вызывается в вашемконтроллер, этот бит логики будет запущен и будет возвращать ошибки проверки как обычно.

0 голосов
/ 21 апреля 2011

Идеальным решением является пользовательский атрибут, в котором вы указываете минимальную и максимальную длину, а также MustNotContain = "Пожалуйста, введите ваше имя ...".

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