我的表单包含默认帮助文本的输入,用于指导用户输入内容(而不是使用标签)。这使验证变得棘手,因为输入值永远不为空。
如何扩展不显眼的验证来处理这个问题?如果姓名输入等于“请输入您的姓名......”
,则表单无效我开始在验证适配器上阅读Brad Wilson's blog post,但我不确定这是否是正确的方法?我需要能够根据字段验证不同的默认值。
由于
答案 0 :(得分:32)
以下是说明如何继续实施自定义验证属性的示例:
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" />
}
答案 1 :(得分:3)
是的,这是正确的方法。您应该实现自己的属性并实现IClientValidatable
。
您还可以将最初设置为false
的必需布尔值作为隐藏表单字段。当用户更改文本框时,将其设置为true。
答案 2 :(得分:0)
您可以使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时,这个逻辑位将被运行,并将正常返回验证错误。
答案 3 :(得分:0)
自问问题以来需要一段时间,但如果您仍然喜欢数据注释,可以使用this library轻松解决此问题:
[Required]
[AssertThat("FieldA != 'some text'")]
public string FieldA { get; set; }
在上面,将字段值与一些预定义的文本进行比较。或者,您可以将字段值相互比较:
[AssertThat("FieldA != FieldB")]
...当比较字符串的情况无关紧要时:
[AssertThat("CompareOrdinalIgnoreCase(FieldA, FieldB) != 0")]
答案 4 :(得分:0)
为了改善@Darin Dimitrov的一些答案,如果您想使用ErrorMessageResourceName and ErrorMessageResourceType
添加来自资源的消息,只需将其添加到错误消息ErrorMessage = ErrorMessage ?? ErrorMessageString
ErrorMessageString将查找您使用这些参数在模型中设置的错误消息的本地化版本(ErrorMessageResourceName和ErrorMessageResourceType)
答案 5 :(得分:-1)
理想的解决方案是自定义属性,您可以在其中指定最小和最大长度以及MustNotContain =“请输入您的姓名......”。