博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

jQuery调用WebService

Posted on 2011-05-11 13:08  guojianlv  阅读(519)  评论(0编辑  收藏  举报
使用jQuery调用WebService发布的方法比调用aspx或ashx页面的方法具有更多的好处,但凡在项目中使用过的人应该都有这样的体会。其中最吸引我的一点就是WebService方法能够接收浏览器端传来的参数并返回能供浏览器端使用的数据,即C#和JavaScript的数据类型能够自动转换并互相识别。其实跨语言本来就是WebService的一大特点,简单来说就是发送方将数据封装成符合W3C规范的XML格式字符串,接收方再把字符串按规范翻译成本语言对应的数据结构。对于JavaScript来说使用XML格式显然不如使用JSON格式有优势,因为JSON本来就是符合JavaScript语法的,也就是原生支持的。

 

举个例子:

 

C#有个Person类
class Person
{
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
public int name;
public int age;
}
Person person = new Person("admin", 30);

 

用XML描述person对象的话可能是这样的(未引入数据类型)
<?xml version="1.0" encoding="utf-8"?>
<persion>
<name>admin</name>
<age>30</age>
</persion>

 

用JSON描述person是这样的
{"name":"admin", "age":30}

 

单纯从形式上看JSON要简洁不少,而且要使用xml的话,你还得按照JavaScript的语法去解析它,上面的这这段xml是没有引入数据类型的,如果数据类型也考虑
进入的话,这个解析过程就会变得很复杂,我不了解网上是不是有现成的解析库,单从简洁性看xml就已经是不可取的,而且也不要对JavaScript解析xml的性能太乐观。

 

使用JSON就简单很多了:
var person = eval('({"name":"admin", "age":30})');
eval是JavaScript语言自带的动态插入函数,还有就是字符串里面的圆括号是不能少的。

 

特别需要注意的是eval接收的JSON格式是很严格的,虽然就语法来说
{"name":"admin", "age":30},{name:"admin", age:30},{name:'admin', age:30},{'name':'admin', 'age':30}都是合法的,但只有第一个能被正确解析。

 

现在我们就可以在服务器端把数据封装成JSON格式的字符串,浏览器端收到的时候调用一下eval函数就可以还原成对象了。
试想一下我们的服务端方法只能返回字符串,这很不直观,而且还要写代码把C#对象转换成JSON格式,虽然有一些现成的类库,但是还是需要一些重复劳动。
在这里jQuery调用WebService的优势就显现出来了。

 

下面说一下是如何调用的,

 

服务器端:
首先引入三个组件:
System.Runtime.Serialization.dll
System.ServiceModel.Web.dll
System.Web.Extensions.dll
这三个组件是.NET3.0新增的,可能很多人跟我一样还在使用2.0,可以直接引用,不用担心不兼容,3.0只是比2.0多了一堆类库而已。如果没有安装3.0运行时的同学可以上网找一下这几个组件,等我弄明白了园里怎么上传以后我会上传一份。

 

第二步就是修改web.config,找到 <system.web> 这个节点,做如下修改
<system.web>
<httpHandlers>
<-- 其他配置内容 -->
<-- 要让WebService自动输出JSON格式,下面两句是关键 -->
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</httpHandlers>
<-- 其他配置内容 -->
</system.web>

 

第三步修改WebService文件(.asmx)
<%@ WebService Language="C#" Class="HandlerService" %>
using System;
using System.Web;
using System.Web.Security;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;
using Spring.Context;
using Spring.Context.Support;
using System.Runtime.Serialization;
[WebService(Namespace = "http://temp.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService] // 没错,要启用JSON功能,就得添加这个特性
public class HandlerService : System.Web.Services.WebService
{
[WebMethod]
public Person CreatePerson(string name, int age)
{
return new Person(name, age+1);
}
}

 

// 添加特性以表明这个类可以被序列化
[DataContract]
class Person
{
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
[DataMember]
public int name;
[DataMember]
public int age;
}

 

 

浏览器端:
我使用的jQuery1.5.2
$.ajax({
        url: 'HandlerService.asmx/CreatePerson', // WebService的地址 + 要调用的方法名
        data: jsonStr, // 要发送的参数,JSON格式的字符串 '{"name":"admin", "age":30}',这些参数会被 CreatePerson(string name, int age)接收,注意格式要严格
        type: 'post', // 这个你懂得
        dataType: 'json', // 期望服务器端返回的数据格式
        contentType: 'application/json; charset=utf-8', // 发送给服务器端的格式
        success: function(data) {
            data = (data && data.d) ? data.d : data; 
// 这样写是为了兼容IIS7(以后再细说),data={"name":"admin", "age":30},注意在这里data是对象而不是字符串,可以这样使用:alert(data.name);
        },            
        complete: function(data) {
            data = (data && data.d) ? data.d : data;
        },
        error: function(exception) {
        }
   });

 

好吧,这里还有一个棘手的问题,就是如何把我们要传给服务器的参数转换成JSON格式的字符串(jsonStr)
在这里介绍一个jQuery插件jquery.json-2.2.min.js
这个插件很好用,但是在IE的兼容模式的某些情况下转换出来的格式不正确,所以如果你的项目使用了ext的话,可以考虑使用它的Ext.util.JSON.encode(o)函数,在
ExtJS/src/ext-core/src/util/JSON.js里的。
var args = {name:'admin', age:30}
var jsonStr = $.toJSON(args);
var jsonStr = Ext.util.JSON.encode(args);