DataAnnotations如何在MVC中真正起作用?

这更像是一个理论问题。

我目前正在使用ComponentModel.DataAnnotations检查MVC 3validation,一切都在自动运行,尤其是在客户端。

某种程度上某些东西检查这些属性,并生成javascript用于validation(或html5属性,如果使用不显眼的模式),它的工作原理。

我的问题是什么生成客户端javascript以及如何访问和修改它? 例如,我想稍微处理给定的dataannotation属性,或处理自定义属性(我发现我可以从ValidationAttribute派生它们,但可能由于某些原因我不想要)。

有人可以向我解释一下真正发生了什么吗? (或者链接到好的解释也会很好,因为我只找到了实际使用数据注释的教程)

编辑:此外,从ValidationAttribute派生,客户端validation不会自动运行。 为什么?

MVC3有一个新的jQueryvalidation机制,它链接jQueryvalidation和validation属性元数据,这是jquery.validate.unobtrusive文件,它接受所有data-属性并使用它们,就像之前设置时一样

  

您需要做的就是提出自己的自定义validation属性 ,因为您有2个选项:

  • 创建自定义validation属性 ,该属性inheritanceValidationAttribute接口并覆盖IsValid

要么

  • 创建自我validation模型使用模型IValidatebleObject ,您只需要返回Validate方法

MVC3中,您现在有一个可以覆盖的方法,它具有ValidationContext对象,您可以在其中获取表单中任何其他对象的所有引用,属性和值

创建您自己的,这个不显眼的文件将处理您的自定义validation器需要的映射,并将与jQuery Validation插件一起使用。

你不要改变javascript …这是sooo 90’s而不是MVC方式!

例如,如果你想validation,假设最后一个不能小于第一个的2个日期(例如时间段)

 public class TimeCard { public DateTime StartDate { get; set; } [GreaterThanDateAttribute("StartDate")] public DateTime EndDate { get; set; } } 

创建自定义validation

 public class GreaterThanDateAttribute : ValidationAttribute { public string GreaterThanDateAttribute(string otherPropertyName) :base("{0} must be greater than {1}") { OtherPropertyName = otherPropertyName; } public override string FormatErrorMessage(string name) { return String.Format(ErrorMessageString, name, OtherPropertyName); } public override ValidateionResult IsValid(object value, ValidationContext validationContext) { var otherPropertyInfo = validationContext.ObjectTYpe.GetProperty(OtherPropertyName); var otherDate = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); var thisDate = (DateTime)value; if( thisDate <= otherDate ) { var message = FormatErrorMessage(validationContext.DisplayName); return new ValidationResult(message); } return null; } } 

如果使用自我validation模型,那么代码就是

 public IEnumerable Validate(ValidationContext validationContext) { if( EndDate <= StartDate ) yield return new ValidationResult("EndDate must be grater than StartDate"); } 

请记住,自定义validation是通用的,这就是为什么许多代码和自我validation模型仅适用于所应用的模型的原因。

希望能帮助到你


添加

我没有解释自定义客户端validation部分,可以随意询问您是否需要示例,但基本上:

在MVC3中更容易(当然,如果你理解jQuery.Validate)你需要做的就是:

  • 实现IClientValidateble
  • 实现jQueryvalidation方法
  • 实现一个不显眼的适配器

要创建这三件事,让我们考虑这个GreaterThanDateAttribute并创建自定义客户端validation。 为此我们需要编写代码:

附加到GreaterThanDateAttribute

 public IEnumerable GetCLientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelCLientValidationRule(); rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()); rule.ValidationType = "greater"; // This is what the jQuery.Validation expects rule.ValidationParameters.Add("other", OtherPropertyName); // This is the 2nd parameter yield return rule; } 

然后你需要编写新的jQuery Validator元数据适配器 ,它将jQuery.Validation链接到你的代码,为该字段提供正确的data-属性(当然, UnobtrusiveJavaScriptEnabled为true)

创建一个新的js文件并附加到 ,例如as

  

并附加新的validation

 jQuery.validator.addMethod("greater", function(value, element, param) { // we need to take value and compare with the value in 2nd parameter that is hold in param return Date.parse(value) > Date.parse($(param).val()); }); 

然后我们编写适配器

 jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function(options) { // pass the 'other' property value to the jQuery Validator options.rules["greater"] = "#" + options.param.other; // when this rule fails, show message that comes from ErrorMessage options.messages["greater"] = options.message; });