SRF之数据验证
实现表单输入数据的验证,包括客户端验证和服务器端验证
如何使用
public class User
{
[Required(ErrorMessage = "请输入姓名")]
public string Name { get; set; }
}
服务器端:
[ClientCustom("isnull", ErrorMessage = "Email不能为空")]
public string Email { get; set; }
JS函数:
function isnull() {
return $(this).val() == "";
}
以上验证方式中DataTypeValidator和ClientCustom是SRF扩展的方式,其它为mvc自带的验证方式,mvc还有更多的验证方式,这里不一一列举。
如何实现
1、自定义验证方式
自定义验证要继承System.ComponentModel.DataAnnotations.ValidationAttribute,其中IsValid()函数实现服务器端验证返回验证是否通过,
客户端验证要实现System.Web.Mvc.IClientValidatable接口,
GetClientValidationRules()返回ModelClientValidationRule集合(包含验证类型、参数、错误提示信息)
如
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelClientValidationRule(); rule.ErrorMessage = base.ErrorMessage; rule.ValidationParameters["pattern"] = this.pattern; rule.ValidationType = "regex"; return new[] { rule }; }
在浏览器的html也将生成
<input data-val="true" data-val-regex="错误提示信息" data-val-regex-pattern="pattern的值" type="text" value="" />
jquery.validate.unobtrusive.js将对根据data-val-regex和data-val-regex-pattern这2个属性做正则表达式的验证
如果要自定义客户端的验证方式,以ClientCustom为例,由于ClientCustom验证方式生成的data-val-custom和data-val-custom-func这中验证方式默认并不支持,所以要在jquery.validate.unobtrusive.js新增adapter,代码如下:
//扩展 zengyy(用自定义函数校验) adapters.add("custom", ["func"], function (options) { var value = options.params.func; setValidationValues(options, "custom", value); }); //扩展 zengyy(用自定义函数校验) $jQval.addMethod("custom", function (value, element, params) { if (params != undefined && params != "") { var func = window[params]; if (func != undefined && typeof func == "function") { return func.call(element, element); } else { return false; } } else { return true; } });
2、验证结果的显示
验证不通过时 mvc3默认是在后边显示提示信息,但这样可能会引起页面布局的改变影响美观,所以改为在输入框的上边以tip的方式显示提示
这种显示方式用到jquery-tipsy这个jQ插件来实现,并修改jquery.validate.unobtrusive.js里边onError()函数的脚本
if (Global && Global.errorShowMode == "tip") { //zengyy:校验错误在上方浮动显示提示 需要用到 jquery.tipsy.cs if (error.html() != "" && $.isFunction(inputElement.tipsy)) { inputElement.attr("original-title", error.html()); inputElement.tipsy({ gravity: 's' }); } else { inputElement.attr("original-title", ""); } }