ASP.NET MVC 3 Validation - 正则表达式验证RegularExpressionAttribute之日期验证
2012-08-09 21:34
661 查看
ASP.NET MVC 3中,正则表达式的验证属性是RegularExpressionAttribute。
问题:
日期格式进行Server端和Client端的验证
解决方案(1):
直接使用RegularExpressionAttribute,写正则表达式。
这样做的好处是比较直接,但当正则表达式比较复杂时,代码会显得并不怎么优雅。
解决方案(2)
从RegularExpressionAttribute直接派生出DateExpressionAttribute
较之方案(1)的做法,好处是能够把正则表达式封装起来,复用性更强(方案(1)中,每个日期验证都需要将正则表达式拷贝一遍,如此代码的维护工作量可想而知)。
建立一个测试model:
page:
再次运行,方案(2)的客户端验证也可以成功触发了。
问题②的原因:
由于我们定义的两个字段都是DateTime类型,故从前台传到后台后,实际去进行验证的时间格式是DateTime(yyyy-MM-dd hh:mm:ss),所以正则表达式必然返回错误(几乎永远不可能通过)。另外,将Client端的验证关掉,输入abc后,返回的错误是"The value "abc" is not a valid value for DateField"。这个错误并不是正则表达式的验证错误,而是当试着把"abc"转换成DateTime类型的时候所抛出的错误,也就是说,你如果输入了无法转换成DateTime类型的值的话,验证是不会经过正则表达式那一端的。当你到达正则表达式验证的时候,输入的日期格式已经被转换成了DateTime了。
此时,可以考虑把DateExpression的Server端验证拿掉,最终代码如下:
若是仍需要加Server端的验证的话,另一个间接方法就是暂时用String来取得Date的值。这样一来不必经过DateTime类型的转化。即便输入了错误的格式,也能够进行Server端的验证,返回期望的错误消息。在Server端验证通过后,再手动将字符串转化为日期格式。
问题:
日期格式进行Server端和Client端的验证
解决方案(1):
直接使用RegularExpressionAttribute,写正则表达式。
[RegularExpression(@"Regular Expression Here", ErrorMessage = "Please input valid date format")] public String RegualarExpressionField { get; set; }
这样做的好处是比较直接,但当正则表达式比较复杂时,代码会显得并不怎么优雅。
解决方案(2)
从RegularExpressionAttribute直接派生出DateExpressionAttribute
public class DateExpressionAttribute : RegularExpressionAttribute { public DateExpressionAttribute() : base("Date Regular Expression Here") { } }
较之方案(1)的做法,好处是能够把正则表达式封装起来,复用性更强(方案(1)中,每个日期验证都需要将正则表达式拷贝一遍,如此代码的维护工作量可想而知)。
建立一个测试model:
public class TestModel
{
[DateExpression]
public DateTime? DateField { get; set; }
[RegularExpression(@"Regular Expression Here", ErrorMessage = "Please input valid date format")] public String RegualarExpressionField { get; set; }
page:
<div> <fieldset> <legend>Account Information</legend> <div class="editor-label"> @Html.LabelFor(m => m.DateField) </div> <div class="editor-field"> @Html.TextBoxFor(m => m.DateField) @Html.ValidationMessageFor(m => m.DateField) </div> <div class="editor-label"> @Html.LabelFor(m => m.RegualarExpressionField) </div> <div class="editor-field"> @Html.TextBoxFor(m => m.RegualarExpressionField) @Html.ValidationMessageFor(m => m.RegualarExpressionField) </div> <p> <input type="submit" value="go!" /> </p> </fieldset> </div>
运行之后会发现两个问题: ①方案(2)中,客户端的验证没有被触发 ②即使输入完全符合正则表达式的值,两个方案经Server端验证后,全部返回验证的错误信息 讨论: 问题①的原因: 我们在DateExpressionAttribute并没有实现IClientValidatable接口,故Client端的验证不会被触发; 修改类如下:
public class DateExpressionAttribute : RegularExpressionAttribute, IClientValidatable { public DateExpressionAttribute() : base(@"Your date regular expression here") { } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "The filed {0} should be a date", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } }
再次运行,方案(2)的客户端验证也可以成功触发了。
问题②的原因:
由于我们定义的两个字段都是DateTime类型,故从前台传到后台后,实际去进行验证的时间格式是DateTime(yyyy-MM-dd hh:mm:ss),所以正则表达式必然返回错误(几乎永远不可能通过)。另外,将Client端的验证关掉,输入abc后,返回的错误是"The value "abc" is not a valid value for DateField"。这个错误并不是正则表达式的验证错误,而是当试着把"abc"转换成DateTime类型的时候所抛出的错误,也就是说,你如果输入了无法转换成DateTime类型的值的话,验证是不会经过正则表达式那一端的。当你到达正则表达式验证的时候,输入的日期格式已经被转换成了DateTime了。
此时,可以考虑把DateExpression的Server端验证拿掉,最终代码如下:
public class DateExpressionAttribute : RegularExpressionAttribute, IClientValidatable { public DateExpressionAttribute() : base(@"((^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(10|12|0?[13578])([-\/\._])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(11|0?[469])([-\/\._])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(0?2)([-\/\._])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\/\._])(0?2)([-\/\._])(29)$)|(^([3579][26]00)([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][0][48])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][0][48])([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][2468][048])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][2468][048])([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][13579][26])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][13579][26])([-\/\._])(0?2)([-\/\._])(29)$))") { } public override bool IsValid(object value) { return true; } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, "The filed {0} should be a date", name); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var name = metadata.GetDisplayName(); var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern); yield return rule; } }
若是仍需要加Server端的验证的话,另一个间接方法就是暂时用String来取得Date的值。这样一来不必经过DateTime类型的转化。即便输入了错误的格式,也能够进行Server端的验证,返回期望的错误消息。在Server端验证通过后,再手动将字符串转化为日期格式。
相关文章推荐
- ASP.NET MVC 3 Validation - 正则表达式验证RegularExpressionAttribute之日期验证
- ASP.NET验证控件RegularExpressionValidator的常见正则表达式
- Asp.net RegularExpressionValidator 控件验证输入值验证输入值是否匹配正则表达式指定的模式
- Asp.net RegularExpressionValidator 控件验证输入值验证输入值是否匹配正则表达式指定的模式
- ASP.NET验证控件RegularExpressionValidator的常见表达式
- Part 83 - RegularExpression attribute in asp.net mvc
- ASP.NET验证控件RegularExpressionValidator的常见表达式
- 正则表达式 验证日期(Asp.net)
- ASP.NET MVC ValidationAttribute 服务器端自定义验证
- asp.net中RegularExpressionValidator控件中正则表达式用法
- asp.net中RegularExpressionValidator控件中正则表达式用法
- ASP.NET MVC ValidationAttribute 服务器端自定义验证
- ASP.NET验证控件RegularExpressionValidator的常见表达式
- ASP.NET验证控件RegularExpressionValidator的常见表达式
- ASP.NET中Validation验证控件正则表达式特殊符号的说明
- ASP.NET MVC ValidationAttribute 服务器端自定义验证
- 【转】【Asp.Net MVC】asp.net mvc Model验证总结及常用正则表达式
- 【转】【Asp.Net MVC】asp.net mvc Model验证总结及常用正则表达式
- ASP.NET中Validation验证控件正则表达式特殊符号的说明