冯东的博客

每天学一点,不断进取
  博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

如何实现WebService的异步调用

Posted on 2007-04-06 12:54  冯东  阅读(7124)  评论(2编辑  收藏  举报
    Ajax之所以能够在互联网上掀起如此高的波澜,就是因为他是异步的,给用户一个良好的体验。接下来我们来谈谈如何在ASP.NET中异步调用WebService
    其实异步调用WebService是不需要在WebService中做任何操作的,只是普通的WebService就可以了,下面是我写的一个简单的WebService返回SqlServer2000中NorthWind数据库中所有员工的信息
[WebMethod]
   
public DLL.EmployeesDataTable getEmployee()
   {
      DLL.EmployeesDataTable result 
= new DLL.EmployeesDataTable();
      DLLTableAdapters.EmployeesTableAdapter eta 
= new WebServiceAsyn.DLLTableAdapters.EmployeesTableAdapter();
      eta.FillEmployee(result);
      
return result;
   }
    这里我需要声明一下,返回的 DLL.EmployeesDataTable类型是我用DataSet生成的强类型,或者你可以认为他是DataTable。
    如何在Asp.Net里引入WebService呢?首先右键单击解决方案资源管理器中的项目,然后选择添加Web引用(你也可以单击网站菜单选择添加Web引用),在弹出的对话框中填入WebService的地址,并填写Web引用名后点击添加引用按钮就可以了,这时我们就可以在代码视图中根据web引用名来对WebService进行调用了,下面是我的CS代码
//实体化WebService引用
private AsynWebService.Service1 asynSer;
//构造函数初始化WebService引用,并为异步调用WebService设置好了结果处理函数【方法名Completed】(先这么叫吧,我也不知道怎么叫)
public _Default()
{
    asynSer 
= new AsynWebService.Service1();
    asynSer.HelloWorldCompleted 
+= new AsynWebService.HelloWorldCompletedEventHandler(asynSer_HelloWorldCompleted);
    asynSer.getEmployeeCompleted 
+= new AsynWebService.getEmployeeCompletedEventHandler(asynSer_getEmployeeCompleted);
}
protected void Button1_Click(object sender, EventArgs e)
{
    
//开始异步调用HelloWorld;
    asynSer.HelloWorldAsync();
}

protected void asynSer_HelloWorldCompleted(object sender, AsynWebService.HelloWorldCompletedEventArgs e)
{
    
this.Label1.Text = e.Result.ToString();
}

protected void asynSer_getEmployeeCompleted(object sender, AsynWebService.getEmployeeCompletedEventArgs e)
{
    
this.GridView1.DataSource = e.Result;
    
this.GridView1.DataBind();
}
protected void Button2_Click(object sender, EventArgs e)
{
    
//开始异步调用getEmployee
    asynSer.getEmployeeAsync();
}
    到这里我们后台代码就写完了,但是我们还要在ASPX页面设置一个允许异步调用的属性 Async="true"这样就可以在这个页面里进行异步调用了!
    同步调用的方法和异步调用的方法不一样,异步调用的方法是WebServic的方法名+Async()作为方法名,同步调用的方法就是WebService的方法名。
    其实从原理上看不管是Ajax还是Asp.Net或者Flex它们的异步调用都是一样的,下面我们来和Ajax比较一下Ajax中的核心对象--XMLHttpRequest对象一个非常重要的属性就是onreadystatechange,下面是一个基于Ajax的简单的用户名的验证
<script language="javascript" type="text/javascript">
    
var xmlHttp;
    
function createXMLHttpRequest()
    {
    
if(window.ActiveXObject)
    {
       xmlHttp 
= new ActiveXObject("Microsoft.XMLHTTP");
    }
    
else if(window.XMLHttpRequest)
    {
       xmlHttp 
= new XMLHttpRequest();
    }        
   }
    
    
function requestStart()
    {
        
if(document.getElementById("tbx1").value.length <= 4)
        {
            alert(
"用户名的长度要求大于4个字符!");
            
return false;
        }
        document.getElementById(
"sp1").innerText = "Loding";
        
var url = "default.aspx?userName=" + document.getElementById("tbx1").value;
    createXMLHttpRequest();
//创建XMLHttpRequest对象
    xmlHttp.onreadystatechange = callBack;//为XMLHttpRequest对象指定结果处理函数
    xmlHttp.open("GET",url);//打开链接
    xmlHttp.send(null);//发送请求
    }
    
//结果处理函数                
    function callBack()
    {
    
if(xmlHttp.readyState == 4)
    {
       document.getElementById(
"sp1").innerText = xmlHttp.responseText;
    }
    }        
</script>
相似之处
1:Ajax需要创建XMLHttpRequest对象,Asp.Net需要实体化WebService代理类对象
2:XMLHttpRequest对象需要指定结果处理函数,Asp.Net也需要指定结果处理函数
3:XMLHttpRequest的结果处理函数必须在请求发送之前设置,Asp.Net同样也是需要在方法被调用之前设置好结果处理函数
接下来我们和Flex比较一下,下面是一个flex中的WebService组件,其中wsdl指明了这个WebService组件将调用哪个WebService,一个WebService组件可以有一个或多个operation,一个operation表示一个WebService的方法,该operation的name属性表示要调用的WebService方法名。
<mx:WebService showBusyCursor="true" id="web1" wsdl="http://localhost/WebServiceAsyn/Service1.asmx?WSDL" useProxy="false">
    
<mx:operation name="HelloWorld" result="this.showHelloWorld()">
    
</mx:operation>
    
<mx:operation name="getEmployee">
    
</mx:operation>
</mx:WebService>
相似之处
1:需要指定结果处理函数
这里还要说明一下,在Flex中WebService默认就是异步调用的,所以我们不能向同步调用那样在发送请求后就处理返回结果,如果返回结果需要处理才能宋显,那么你必须定义一个结果处理函数!