我正在为我的 MVC4 应用程序构建一个自定义验证器。为了简单起见并专注于这个问题的目的,假设我正在重新实现RequiredAttribute
类的服务器和客户端验证:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MyRequiredAttribute: ValidationAttribute, IClientValidatable
{
public MyRequiredAttribute() : base("The {0} field is required.")
{
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return null;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRequiredRule(ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()));
}
}
为了测试这一点,我有一个非常简单的控制器:
public class TestController : Controller
{
public ActionResult Index()
{
return View(new MyThing {Value = "whatever"});
}
[HttpPost]
public ActionResult Index(MyThing thing)
{
if (ModelState.IsValid)
{
return Content("Good choice!");
}
return View(thing);
}
}
和一个非常简单的模型:
public class MyThing
{
[MyRequired]
public string Value { get; set; }
[Required]
public string OtherValue { get; set; }
}
最后是索引视图:
@model MyThing
@{
Layout = "~/Views/Shared/_LayoutWithAllTheAppropriateValidationScripts.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
@using(Html.BeginForm()){
@Html.ValidationSummary(true)
@Html.EditorForModel()
<input type="submit" value="submit"/>
}
</div>
</body>
</html>
你会注意到我有Value
一个用 custom 装饰的MyRequiredAttribute
,OtherValue
一个用 standard 装饰的RequiredAttribute
。
这两个都在服务器端工作得很好,并在回发时返回适当的验证消息,但只有标准RequiredAttribute
在客户端工作。由于我使用的是 aModelClientValidationRequiredRule
而不是ModelClientValidationRule
带有自定义ValidationType
属性的 a,因此我假设不需要定义自定义客户端验证规则,但我不确定这一点,因为我还没有做到这一点。调试器永远不会在GetClientValidationRules
方法内部中断,并且为我的模型上的属性生成的输入 html 元素Value
没有data-val-required
和data-val
字段一样的属性OtherValue
,我假设这是GetClientValidationRules
方法负责做的事情。
我必须在这里遗漏一些简单的东西......它是什么?