Webservice与ExtJS结合的应用中有许多细节值得注意,下面就从Visual Studio创建一个Webservice项目开始,首先启动Visual Studio并新建一个“Asp.Net Web服务应用程序”或“Asp.Net Web应用程序”,新建项目命名为“TestWebService”,如下图所示:
打开项目中默认新建的Service1.asmx文件(如果没有asmx,则新建一个“Web服务”),代码如下:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
[System.Web.Script.Services.ScriptService] //这句非常重要
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
值得注意的是上面红色字体部分,这句非常重要,如果没有这句,即使Webservice发布成功,ExtJS仍然不能调用返回Json数据。直接编译该项目,然后在本地发布,如采用IIS,如下图所示:
调用HelloWorld方法,将返回其相应的结果,如下图所示:
接下来在ExtJS中编写获取该方法返回值的相应代码。同样,在ExtJS项目中新建一个Webservice.html网页,其内容如下:
<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8; user-scalable=no">
<title>Webservice</title>
<link rel="stylesheet" type="text/css"href="resources/css/ext-all.css"/>
<scripttype="text/javascript"src="bootstrap.js"></script>
<script type="text/javascript"src="Webservice.js"></script>
</head>
<body>
</body>
</html>
然后新建一个Webservice.js文件,在其中添加如下代码:
Ext.onReady(function(){
Ext.Ajax.request({
url:'http://192.168.1.102/ExtJS/Webservice/TestWebservice/TestWebService/Service1.asmx/HelloWorld', //Webservice发布地址
method:'POST',
headers:{'Content-Type':'application/json;utf-8'},//在这里一定要指定头信息为json,否则将返回的是XML,而不是Json
success:function(response,options){
Ext.Msg.alert('成功',response.responseText);
},
failure:function(){
Ext.Msg.alert('失败','与Webservice连接失败');
}
});
});
值得注意的是:url中的地址为Webservice发布的地址,并且包括调用方法名称(例如此次调用HelloWorld的方法,所以在asmx后加上该方法名)。经过测试发现如果Webservice不发布,尽管js文件与asmx之间的关系为相对路径,此次url也设置为相对路径或绝对路径,都会出现访问失败,所以建议先将Webservice发布。如果也将ExtJS也发布了,那么此次url地址可以采用相对于Webservice发布地址的相对路径,但是还是建议先采用全地址进行访问,在测试成功之后再更改为相对发布路径。此外,method的值设置为POST,headers属性用于指定返回为Json数据,默认返回xml数据。success用于表示获取成功时执行的函数,其中参数response为返回数据对象,options为请求调用的参数,response.responseText为返回数据转换为字符串的内容。保存js文件,用浏览器打开Webservice.html网页(注意:如果是采用Firefox,建议将Webservice.html网页先发布再浏览该网页,否则可能无法获取Webservice中的数据;如果是采用IE,则直接打开该文件),其结果如下图所示:
前面发布的Webservice中只有一个方法,且为无输入参数的方法,下面以带输入参数为例来说明在这种情况下Webservice如何ExtJS结合。同样在Webservice的Service1.asmx文件中新建一个函数GetStudentInfo,如下(Service1.asmx.cs文件中):
[WebMethod]
public ArrayList GetStudentInfo(stringusername, string pwd)
{
ArrayListresult = new ArrayList();
if(username == "admin" &&pwd == "123")
{
ArrayList tempReocrd = newArrayList();
tempReocrd.Add("张三");
tempReocrd.Add("男");
tempReocrd.Add(25);
tempReocrd.Add(DateTime.Now.ToString());
result.Add(tempReocrd);
tempReocrd = new ArrayList();
tempReocrd.Add("李四");
tempReocrd.Add("男");
tempReocrd.Add(28);
tempReocrd.Add(DateTime.Now.ToString());
result.Add(tempReocrd);
}
returnresult;
}
在浏览器中访问这个Webservice服务,其结果为:
然后将Webservice.js文件的内容改为如下(红色字体为更改部分):
Ext.onReady(function(){
Ext.Ajax.request({
url:'http://192.168.1.102/ExtJS/Webservice/TestWebservice/TestWebService/Service1.asmx/GetStudentInfo', //Webservice发布地址
method:'POST',
jsonData:{username:'admin', pwd:'123'},
headers:{'Content-Type':'application/json;utf-8'},//在这里一定要指定头信息为json,否则将返回的是XML,而不是Json
success:function(response,options){
Ext.Msg.alert('成功',response.responseText);
var data=Ext.JSON.decode(response.responseText); //解析数据
},
failure:function(){
Ext.Msg.alert('失败','与Webservice连接失败');
}
});
});
由于在调用Webservice服务的GetStudentInfo方法的时候需要传递参数,所以在ExtJS中需要定义参数jsonData,其中里面的参数名称需要和GetStudentInfo方法的参数名称一致,即GetStudentInfo方法中的第一个参数名称为username,那么在此jsonData的第一个参数也应该为username,传递的参数值可以都采用字符串来传递。其结果如下图所示:其返回的数据为{"d":[["张三","男",25,"2012/7/318:43:28"],["李四","男",28,"2012/7/31 8:43:28"]]} ,通过Ext.JSON.decode方法可以进行解析,返回的对象data的d(data.d)即为张三,男,25,2012/7/318:44:37,李四,男,28,2012/7/318:44:37。data.d[1]就是data.d的第二个数组,即李四,男,28,2012/7/318:44:37。同理,data.d[1][0]即为 李四 ,data.d[1][1]即为 男。但是这样再解析还是有一些麻烦,需要将字符串分解,并且没有返回每个值的含义。如果要返回的Json带有名称,那么就在Webservice上直接返回这些对象,如在此要返回每个学生的信息,那么先自定义一个学生类Student,然后在GetStudentInfo2方法中返回该对象,如下代码(Service1.asmx.cs文件中):
///<summary>
///自定义学生类
///</summary>
publicclass Studenet
{
publicstring Name;
publicstring Gender;
publicint Age;
}
[WebMethod]
publicStudenet[] GetStudentInfo2(string username, stringpwd)
{
Studenet[]students = null;
if(username == "admin" &&pwd == "123")
{
students = new Studenet[2];
students[0] = new Studenet();
students[0].Name = "张三";students[0].Gender = "男"; students[0].Age = 25;
students[1] = new Studenet();
students[1].Name = "李四";students[1].Gender = "男"; students[1].Age = 28;
}
returnstudents;
}
发布Webservice,然后调用GetStudentInfo2方法,其返回结果如下:然后修改Webservice.js文件的内容改为如下(红色字体为更改部分):
Ext.onReady(function(){
Ext.Ajax.request({
url:'http://localhost/ExtJS/Webservice/TestWebservice/TestWebService/Service1.asmx/GetStudentInfo2', //Webservice发布地址
method:'POST',
jsonData:{username:'admin', pwd:'123'},
headers:{'Content-Type':'application/json;utf-8'},//在这里一定要指定头信息为json,否则将返回的是XML,而不是Json
success:function(response,options){
//Ext.Msg.alert('成功',response.responseText);
var data=Ext.JSON.decode(response.responseText); //解析数据
var data2 = data.d;
Ext.Msg.alert('成功','返回Json数据:<br\>'+response.responseText
+'<br\>姓名:'+data.d[0].Name
+'<br\>性别:'+data.d[0].Gender
+'<br\>年龄:'+data.d[0].Age);
},
failure:function(){
Ext.Msg.alert('失败','与Webservice连接失败');
}
});
});
上面通过返回的Json数据解析,读取每个学生的信息(以上例子中只读取了第一个学生的信息,即data.d[0])。其结果如下图所示:
如果返回多个数据(返回多条记录,多个学生的信息)时,可以通过遍历数据的每个对象来获取数据,如下(红色字体为更改部分):
Ext.onReady(function(){
Ext.Ajax.request({
url:'http://localhost/ExtJS/Webservice/TestWebservice/TestWebService/Service1.asmx/GetStudentInfo2', //Webservice发布地址
method:'POST',
jsonData:{username:'admin', pwd:'123'},
headers:{'Content-Type':'application/json;utf-8'},//在这里一定要指定头信息为json,否则将返回的是XML,而不是Json
success:function(response,options){
//Ext.Msg.alert('成功',response.responseText);
var data=Ext.JSON.decode(response.responseText); //解析数据
var msg='';
varjson = data.d;
for(var index = 0, len = json.length; index < len; index++) {
var name =json[index].Name //Name属性
var gender =json[index].Gender; //Gender属性
var age =json[index].Age; //Age属性
msg=msg+'<br\>'+'姓名:'+name+' 性别:'+gender+' 年龄:'+age;
}
Ext.Msg.alert('成功',msg);
},
failure:function(){
Ext.Msg.alert('失败','与Webservice连接失败');
}
});
});
其结果如下图所示: