这更像是一个理论问题。
我目前正在使用 ComponentModel.DataAnnotations 检查 MVC 3 验证,一切都自动运行,尤其是在客户端。
有些东西会检查这些属性,并生成用于验证的 javascript(或 html5 属性,如果使用非侵入式模式),并且它有效。
我的问题是什么生成客户端 javascript,我如何访问和修改它?例如,我想以稍微不同的方式处理给定的 dataannotation 属性,或者处理自定义属性(我发现我可以从 ValidationAttribute 派生它们,但也许出于某种原因我不想要)。
谁能给我解释一下到底发生了什么? (或者指向好的解释的链接也很好,因为我只找到了实际使用数据注释的教程)
编辑:同样从 ValidationAttribute 派生,客户端验证不会自动工作。为什么?
最佳答案
MVC3 有一个新的 jQuery 验证机制,它链接 jQuery 验证和验证属性元数据,这是 jquery.validate.unobtrusive
包含所有 data-
的文件属性并使用它们,就像之前设置
<add key="UnobtrusiveJavaScriptEnabled" value="false" />
您需要做的就是想出您自己的自定义验证属性,为此您有两个选择:
- 创建继承
ValidationAttribute
的自定义验证属性接口(interface)和 覆盖IsValid
或
- 创建 self 验证模型使用模型
IValidatebleObject
你只需要返回Validate
方法
在 MVC3 中,您现在有一个可以覆盖的方法,该方法具有 ValidationContext
对象,您可以在其中简单地获取表单中任何其他对象的所有引用、属性和值
创建您自己的文件,这个不显眼的文件将处理您的自定义验证器需要的映射,并将与 jQuery 验证插件一起工作。
您不要更改 javascript...那是 90 年代的风格,而不是 MVC 方式!
例如如果你想验证,假设最后一个不能小于第一个的 2 个日期(例如时间段)
public class TimeCard
{
public DateTime StartDate { get; set; }
[GreaterThanDateAttribute("StartDate")]
public DateTime EndDate { get; set; }
}
创建自定义验证
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;
}
}
如果使用自验证模型,那么代码就是
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if( EndDate <= StartDate )
yield return new ValidationResult("EndDate must be grater than StartDate");
}
请记住,自定义验证是通用的,这就是为什么很多代码和自验证模型仅适用于所应用的模型。
希望对您有所帮助
已添加
我没有解释自定义客户端验证部分,随意询问您是否需要示例,但基本上:
在 MVC3 中更容易(当然,如果您了解 jQuery.Validate),您需要做的就是:
- 实现
IClientValidateble
- 实现一个 jQuery 验证方法
- 实现一个不显眼的适配器
要创建这 3 个东西,让我们用这个 GreaterThanDateAttribute
考虑并创建自定义客户端验证。为此,我们需要编写以下代码:
附加到 GreaterThanDateAttribute
public IEnumerable<ModelCLientValidation> 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
为真)
创建一个新的 js
文件并附加到您的 <head>
例如
<script src="@Url.Content("~/Scripts/customValidation.js")" type="text/javascript"></script>
并附加新的验证
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;
});
关于c# - DataAnnotations 在 MVC 中是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5154231/