[jQuery]使用jQuery.Validate进行客户端验证(高级篇-下)——不使用微软验证控件的理由-阿里云开发者社区

开发者社区> zting科技> 正文

[jQuery]使用jQuery.Validate进行客户端验证(高级篇-下)——不使用微软验证控件的理由

简介:
+关注继续查看

继续上一篇文章使用jQuery.Validate进行客户端验证(高级篇-上),本文将继续介绍jQuery.Validate的高级应用——jQuery.Validate的AJAX验证及简单扩展。

今天主要介绍的内容有:

1、如何使用jQuery.Validate进行AJAX验证?

2、默认jQuery.Validate在进行AJAX验证时返回必须是bool类型,如何返回一个对象包括错误消息及验证结果?

3、在反复使用jQuery.Validate进行AJAX验证时,总是需要编写相关AJAX参数,可否进行进一步封装?

 

第一点:如何使用jQuery.Validate进行AJAX验证?(具体见High-2.aspx

jQuery.Validate为我们提供了一个方便的AJAX验证方式(封装了jQuery的AJAX,同时将jQuery的AJAX和jQuery.Validate的验证很好的结合在一起),在此我仅仅介绍jQuery.Validate在ASP.NET下如何进行AJAX验证,PHP、JSP等请查看官方例子。

我是采用jQuery.Validate+WebService进行AJAX验证,客户端编写jQuery.Validate的remote验证属性,服务器端采用WebSerice进行接收参数进行验证。

首先来看下jQuery.Validate的remote属性如何编写AJAX验证规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function InitRules() {
            opts = {
             rules:
                {
                    <%=txtUid.UniqueID %>:
                    {
                        required: true,
                        remote:{
                            type: "POST",
                            async: false,
                            url: "WebService.asmx/CheckUid",
                            dataType: "xml",
                            data: {uid:function(){ return jQuery("#<%=txtUid.ClientID %>").val();}}
                        }
                    }
                }
            }
        }

如果使用过jQuery.ajax的朋友肯定会很熟悉这段代码,jQuery.Validate的remote采用和jQuery.ajax相同的参数设置(原因就上面所说的封装了jQuery.ajax的原因)。

这边来详细讲解下jQuery.Validate的remote的一些知识:

1、jQuery.Validate的remote默认可以直接填写远程验证的地址,格式为:remote:”validate.aspx”,但是很多情况下这个远程验证需要提交参数、返回类型等限制,所以就可以采用在“{}”中编写具体属性的方式来包装提交参数。

2、jQuery.Validate的remote官方代码中,远程的输出只能是true或者false,不允许有其他输出,这个我觉得不太好,具体的扩展在后面我会讲到

3、jQuery.Validate的remote在使用时如果想提交参数需要以JSON的方式提交格式如下:

1
2
3
4
5
data: {
        uid:function(){
                return jQuery("#<%=txtUid.ClientID %>").val();
        }
}

此处肯定会有人不明白,为什么参数需要以function的形式提交,而不是直接写

jQuery("#<%=txtUid.ClientID %>").val();

这里我要说明的是:jQuery.Validate的验证规则是在页面加载的时候就已经被加载了的,如果还是像以往一样直接写"jQuery("#<%=txtUid.ClientID %>").val();",那么验证的时候提交给服务器端的数据永远是页面加载时txtUid控件的值。

而使用function的好处就是在页面加载的时候仅仅告诉jQuery.Validate,在控件需要进行remote验证的时候需要调用function这个函数,这样就保证了在执行remote验证的时候可以获取到最新的值

我还修改了jQuery.Validate的remote方法,先来看下我修改的代码(具体见scripts/jquery.validate1.js 896行):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (previous.old !== value) {
    previous.old = value;
    var validator = this;
    this.startRequest(element);
    var data = {};
    data[element.name] = value;
    $.ajax($.extend(true, {
        //url:url,//此URL无法获取
        url: param.url,//获取param验证规则中所写路径
        mode: "abort",
        port: "validate" + element.name,
        type: param.type,
        dataType: "json",
        //data:data,
        data: param.data || data,//获取param.data或data中所提交的参数
        success: function(response) {
        以下省略...
}

这边我修改了url和data的获取方式,主要是因为在真正执行的时候,变量url是空的,所以需要从param中获取。

而data为什么要改成param.data || data,主要原因就是下面这句代码:

data[element.name] = value;

这句代码的意思就是:为哪个控件设置远程验证就获取哪个控件的值,但是在实际的开发中,当遇到进行AJAX验证的时候会出现需要同时提交多个数据的情况,此时这句代码就是错误的了,所以需要改成

param.data || data,这样就能保证在提交多个数据的时候以多个数据为准。

下面来看下webservice的代码:

1
2
3
4
5
[WebMethod]
public bool CheckUid(string uid)
{
    return uid == "testuid" ? true : false;
}

相当的简单,就是判断下用户名是不是指定的用户名。

注意:webservice.cs中必须将[System.Web.Script.Services.ScriptService]这个特性取消注释,否则AJAX验证将无效!

 

第二点:默认jQuery.Validate在进行AJAX验证时返回必须是bool类型,如何返回一个对象包括错误消息及验证结果?(具体见App_Code/WebService.cs/CheckUid

在第一点中介绍jQuery.Validate知识的时候就提到了,jQuery.Validate默认直接收true或false,但是在具体的开发中,我们会分层开发,三层或者多层,webservice在接收到验证请求后不做具体的处理直接调用逻辑层的验证方法,交由逻辑层进行验证操作(当然你也可以把验证全部写在webservice中,但是这样就体现不出分层的好处了),此时的验证会产生多种情况,以最常见的用户名验证为例:

    1)用户名已存在,此时的消息应该是“用户名已存在,请重新输入!”

    2)用户名不符合规则,此时的消息应该是“用户名不符合规则,请重新输入!”

    3)验证时出现程序异常,此时的消息应该是“程序出现异常,请联系管理员!”

可以看出,仅仅一个用户名验证就会出现这3种信息,如果不返回一个明确的消息,仅仅告诉用户“用户名有误”,客户端的使用者将会相当的痛苦,因为使用者并不知道他的用户名输入到底错在哪了。

所以为了更好的客户体验,以及项目的合理性,我们在服务器端封装一个实体类(具体见AppCode/AjaxClass),代码如下:

1
2
3
4
5
6
[Serializable]
public class AjaxClass
{
    public string Msg { get; set; }
    public int Result { get; set; }
}

就是一个最简单的实体类,有2个属性,Msg和Result,Msg用于存放验证失败的信息,Result用于存放结果。

 

看下WebSerivce的代码如何修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[WebMethod]
public AjaxClass CheckUid(string uid)
{
    //return uid == "testuid" ? true : false;
    AjaxClass ajaxClass = new AjaxClass();
    try
    {
        if (uid == "testuid")
        {
            ajaxClass.Msg = "用户名已存在,请重新输入!";
            ajaxClass.Result = 0;
        }
        else if (uid.IndexOf("test") == -1)
        {
            ajaxClass.Msg = "用户名格式不正确,用户名必须包含test,请重新输入!";
            ajaxClass.Result = 0;
        }
        else
        {
            ajaxClass.Msg = "格式正确!";
            ajaxClass.Result = 1;
        }
    }
    catch
    {
        ajaxClass.Msg = "程序出现异常,请联系管理员!";
        ajaxClass.Result = 0;
    }
    return ajaxClass;
}

上面的WebService就完整的实现了我先前说的3种错误情况(由于这边仅仅是例子所以就只有表示层,实际开发中需要分层开发,此代码应该放入业务逻辑层

注意:在webservice返回值前,如果检查成功必须要为ajaxClass.Result = 1,否则客户端验证会无法通过。

虽然完成了服务器端的代码修改,但是直接运行页面还是会出错,这是因为我上面所说过的,jQuery.Validate的remote远程的输出只能是true或者false,我们来看下具体的代码,其中注释掉的就是原来官方的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
success: function(response) {
    if (response.Result) {//if(response){
        var submitted = validator.formSubmitted;
        validator.prepareElement(element);
        validator.formSubmitted = submitted;
        validator.successList.push(element);
        validator.showErrors();
    } else {
        var errors = {};
        //errors[element.name] = response.Result || validator.defaultMessage(element, "remote");
        errors[element.name] = response.Msg;
        validator.showErrors(errors);
    }
    previous.message = response.Msg; //previous.valid = response;
    previous.valid = response.Result;
    validator.stopRequest(element, response.Result);
}

可以看到一共修改了3处地方:

1、判断返回值,原来是直接判断response,现在则是判断response.Result,因为现在的response已经是一个包含消息及结果的对象了。

2、错误消息,原来的错误消息是直接获取默认配置好的消息,我这边是获取response.Msg。

3、设置previous对象,将previous对象的消息和结果设置为AJAX返回的消息和结果,以供jQuery.Validate下面代码的返回。

这样jQuery.Validate的remote的方法就修改了,但是并没有结束,原因是先前在AJAX提交参数的时候由于jQuery.Validate的验证规则的缘故,提交的参数并不是以JSON的格式提交的而是以{uid:function()}这样的方式,结果就导致了无法设置jQuery.AJAX的contentType:"application/json; charset=utf-8",如果设置了会出现以下错误:

pic24这样从webservice返回的AjaxClass对象就无法像以往的JSON方式直接操作了,所以我们只能换一种格式——XML,因为webservice默认返回的数据是XML格式:

1
2
3
4
5
<?xml version="1.0" encoding="utf-8" ?>
- <AjaxClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
  <Msg>用户名格式不正确,用户名必须包含test,请重新输入!</Msg>
  <Result>0</Result>
  </AjaxClass>

接下来看下具体的remote方法应该如何编写,设置dataType:”xml”,然后将XML数据转换成一个对象以供上面我修改的jQuery.Validate的remote方法中ajaxsuccess的使用,具体看一下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
remote:{
    type: "POST",
    dataType:"json",
    async: false,
    url: "WebService.asmx/CheckUid",
    data: {uid:function(){ return jQuery("#<%=txtUid.ClientID %>").val();}},
    dataFilter: function(dataXML) {
        var result = new Object();
        result.Result = jQuery(dataXML).find("Result").text();
        result.Msg = jQuery(dataXML).find("Msg").text();
        if (result.Result == "-1") {
            result.Result = false;
            return result;
        }
        else {
            result.Result = result.Result == "1" ? true : false;
            return result;
        }
    }
}

就是jQuery.Ajax方法dataFilter,可以在AJAX请求成功后将数据进行过滤处理,这里我就使用了jQuery方法把结果和消息从XML中获取出来直接赋给一个对象,再将这个对象返回,交由ajaxsuccess使用。

这样就算是完成了修改jQuery.Validate的remote方法,使得可以返回验证结果及验证消息,看下效果图:

pic25

 

第三点:在反复使用jQuery.Validate进行AJAX验证时,总是需要编写相关AJAX参数,可否进行进一步封装?(具体见High-3.aspx和jquery.validate.extension.js)

在开发一个系统的时候经常会用到AJAX的验证,而如果每次都要编写上面那么多的代码还是很不方便,所以我现在就来进行一下简单的封装,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//远程验证抽象方法
function GetRemoteInfo(postUrl, data) {
    var remote = {
        type: "POST",
        async: false,
        url: postUrl,
        dataType: "xml",
        data: data,
        dataFilter: function(dataXML) {
            var result = new Object();
            result.Result = jQuery(dataXML).find("Result").text();
            result.Msg = jQuery(dataXML).find("Msg").text();
            if (result.Result == "-1") {
                result.Result = false;
                return result;
            }
            else {
                result.Result = result.Result == "1" ? true : false;
                return result;
            }
        }
    };
    return remote;
}

这个函数主要接收2个参数,一个是远程验证的路径和需要提交的参数,返回包装好的remote对象。

页面调用也很简单,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script src="scripts/jquery.validate.extension.js" type="text/javascript"></script>
    <script type="text/javascript">
        function InitRules() {
            var dataInfo = {uid:function(){ return jQuery("#<%=txtUid.ClientID %>").val();}};
            var remoteInfo = GetRemoteInfo('WebService.asmx/CheckUid', dataInfo);
 
            opts = {
             rules:
                {
                    <%=txtUid.UniqueID %>:
                    {
                        required: true,
                        remote:remoteInfo
                    }
                }
            }
        }
    </script>

怎么样?相比上面的代码一下子干净了很多吧?

页面上只要做3步操作:

1、包装好需要提交的data对象。

2、将远程验证地址和包装好的data对象传递给封装好的方法获取remote对象。

3、将函数返回的remote对象放入规则中。

 

至此使用jQuery.Validate进行客户端验证——不使用微软验证控件的理由这一系列就算全部写完了,大体上将jQuery.Validate在ASP.NET上的一些常见应用讲了一下,同时也提出了许多我自己修改扩展的东西,希望对正在苦恼客户端验证的朋友有所帮助,谢谢大家的支持了!

PS:1、其实这一系列并没有把jQuery.Validate的所有功能介绍完,比如onfocusin,onfocusout,onkeyup等,这些就需要大家在使用的过程中自己查看源代码实验了。

2、本文有点长,而且内容比较多,如果文中有什么错误或者有指导意见欢迎大家提出来,谢谢了!

源代码下载:点我下载



本文转自kyo-yo博客园博客,原文链接:http://www.cnblogs.com/kyo-yo/archive/2010/07/06/Use-jQuery-Validate-To-Being-Client-Validate-High-2.html,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
netty系列之:搭建客户端使用http1.1的方式连接http2服务器
对于http2协议来说,它的底层跟http1.1是完全不同的,但是为了兼容http1.1协议,http2提供了一个从http1.1升级到http2的方式,这个方式叫做cleartext upgrade,也可以简称为h2c。 在netty中,http2的数据对应的是各种http2Frame对象,而http1的数据对应的是HttpRequest和HttpHeaders。一般来说要想从客户端发送http2消息给支持http2的服务器,那么需要发送这些http2Frame的对象,那么可不可以像http1.1这样发送HttpRequest对象呢? 今天的文章将会给大家揭秘。
52 0
【jQuery 使用】 利用jQuery.prop("outerHTML")获取包含自身在内的HTML元素的HTML代码
jQuery.html() 是获取当前节点下的html代码,并不包含当前节点本身的代码,然而我们有时候的确需要,可以通过jQuery.prop("outerHTML")的方式设置。 很多jQuery的使用者都对这一问题深感疑惑。
854 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10073 0
Memcached学习笔记 — 第四部分:Memcached Java 客户端-gwhalin(1)-介绍及使用
 介绍 Memcached java client是官方推荐的最早的memcached java客户端。最新版本:java_memcached-release_2.6.1。 官方下载地址:https://github.com/gwhalin/Memcached-Java-Client采用阻塞式SOCKET通讯,据说目前版本进行了很多优化,性能有所提高(只看过1.5的源代码,还没来及看
986 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13882 0
Linux环境下使用图形化界面的SVN客户端软件-RabbitVCS
如果想在Linux环境下使用图形化界面的SVN客户端软件,那么RabbitVCS绝对是首选,可以媲美Windows环境下用的TortoiseSVN,甚至连操作都基本一样,所以强烈推荐给各位童鞋。 RabbitVCS基本支持所有的Linux发行版本包括Ubuntu、Debian、Fedora、Arch Linux、Gentoo、Mandriva、OpenSUSE、RHEL、CentOS 5等。
1749 0
+关注
3550
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载