Mvc3 подтверждать ввод "не равным",
У моих форм есть вкладки со вспомогательным текстом по умолчанию, который направляет пользователя на то, что вводить (а не использовать метки). Это делает проверку достоверной, поскольку входное значение никогда не является нулевым.
Как я могу расширить ненавязчивую проверку, чтобы справиться с этим? Форма не должна быть действительной, если вход Name равен "Пожалуйста, введите свое имя..."
Я начал читать сообщение в блоге Brad Wilson об адаптерах проверки, но я не уверен, что это правильный путь? Мне нужно уметь проверять разные значения по умолчанию в зависимости от поля.
Спасибо
Ответы
Ответ 1
Да, это правильный путь. Вы должны реализовать свой собственный атрибут и реализовать IClientValidatable
.
Вы также можете иметь требуемое логическое значение, первоначально заданное в false
как скрытое поле формы. Когда пользователь меняет текстовое поле, установите для него значение true.
Ответ 2
Вот пример, иллюстрирующий, как вы могли бы перейти к реализации пользовательского атрибута проверки:
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
Вы можете сделать свой 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, этот бит логики будет запущен и вернет ошибки проверки как обычно.
Ответ 4
Потребовалось немного времени, так как ваш вопрос был задан, но если вам все еще нравятся аннотации данных, эту проблему можно легко решить, используя эту библиотеку
[Required]
[AssertThat("FieldA != 'some text'")]
public string FieldA { get; set; }
Выше, значение поля сравнивается с некоторым заранее определенным текстом. Кроме того, вы можете сравнивать значения полей друг с другом:
[AssertThat("FieldA != FieldB")]
... и когда случай сравнения строк не имеет значения:
[AssertThat("CompareOrdinalIgnoreCase(FieldA, FieldB) != 0")]
Ответ 5
Чтобы улучшить немного ответа @Darin Dimitrov, если вы хотите добавить сообщения из ресурсов с помощью ErrorMessageResourceName and ErrorMessageResourceType
, просто добавьте это в сообщение об ошибке ErrorMessage = ErrorMessage ?? ErrorMessageString
ErrorMessageString будет искать локализованную версию сообщения об ошибке, которое вы установили в модели, используя эти параметры (ErrorMessageResourceName и ErrorMessageResourceType)
Ответ 6
Идеальные решения - это настраиваемый атрибут, в котором вы указываете минимальную и максимальную длину, а также MustNotContain = "Пожалуйста, введите свое имя...".