这个帖子本16号放在首页,不知道为何不见了,也许是我误删除了吧,重新补上,放在我自己的首页。最近在做手机上一程序,需要通过移动cmwap访问外部的webservice,但使用wsdl生成的代理类通过cmwap网关访问会出现"Client found response content type of 'text/vnd.wap.wml',but expected 'text/xml' ".的异常信息,换用cmnet网络则正常。应该是通过cmwap网关请求返回的数据被转化为wml类型了,wsdl代理类只认xml;把google翻了也找不到解决方案,只好自己用最笨的办法,用HttpWebRequest和HttpWebResponse实现访问soap协议。
代码如下:
这个帖子本16号放在首页,不知道为何不见了,也许是我误删除了吧,重新补上,放在我自己的首页。
最近在做手机上一程序,需要通过移动cmwap访问外部的webservice,但使用wsdl生成的代理类通过cmwap网关访问会出现"Client found response content type of 'text/vnd.wap.wml',but expected 'text/xml' ".的异常信息,换用cmnet网络则正常。
应该是通过cmwap网关请求返回的数据被转化为wml类型了,wsdl代理类只认xml;
把google翻了也找不到解决方案,只好自己用最笨的办法,用HttpWebRequest和HttpWebResponse实现访问soap协议。
代码如下:
![](/Images/OutliningIndicators/ContractedBlock.gif)
SoapClient
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//*
code by Aijoe(原 Ivan Chin)
http://www.lostway.net/
http://www.cnblogs.com/drw/
aijoe@lostway.net
转载请保留此信息。
*/
![](/Images/OutliningIndicators/None.gif)
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml;
![](/Images/OutliningIndicators/None.gif)
namespace IvanCF.Soap
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
internal class SoapClient
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
属性#region 属性
![](/Images/OutliningIndicators/InBlock.gif)
private string nameSpace = "http://tempurl.org/";
private Uri serviceUrl;
private IWebProxy webProxy = null;
private ICredentials credentials = null;
private int timeOut = 30000;
private Encoding encoding = Encoding.GetEncoding("UTF-8");
![](/Images/OutliningIndicators/InBlock.gif)
//设置请求的webservice命名空间
public string Namespace
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return nameSpace; }
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ nameSpace = value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
//webservice地址
public Uri ServiceUrl
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return serviceUrl; }
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ serviceUrl = value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
//客户端使用代理
public IWebProxy Proxy
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return webProxy; }
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ webProxy = value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
//客户端验证
public ICredentials Credentials
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return credentials; }
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ credentials = value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
//webservice请求编码格式
public Encoding ContentEncoding
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return encoding; }
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ encoding = value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
//超时时间
public int TimeOut
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return timeOut; }
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ timeOut = value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
private const int BUFFER_SIZE = 512;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
异步方法#region 异步方法
![](/Images/OutliningIndicators/InBlock.gif)
//用于操作等待线程。
public static ManualResetEvent allDone = new ManualResetEvent(false);
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
实现事件完成通知#region 实现事件完成通知
![](/Images/OutliningIndicators/InBlock.gif)
//异步调用完成的事件
public event SoapInvokeCompletedEventHandler SoapInvokeCompleted;
protected virtual void OnSoapInvokeCompleted(SoapInvokeCompleteArgs args)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (SoapInvokeCompleted != null)
SoapInvokeCompleted(this, args);
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 异步调用webService的方法
/// </summary>
/// <param name="methodName">调用的webService的方法名称</param>
/// <param name="parameters">发送的数据</param>
public void InvokeAsync(string methodName, PostDataArray parameters)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
RequestState state = new RequestState();
state.MethodName = methodName;
state.Parameters = parameters;
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
state.Request = (HttpWebRequest) WebRequest.Create(ServiceUrl);
if (TimeOut > 0) state.Request.Timeout = TimeOut;
if (Proxy != null) state.Request.Proxy = Proxy;
if (Credentials != null) state.Request.Credentials = Credentials;
state.DataSend.Append(ResloveSendData(methodName, parameters));
state.Request.ContentLength = ContentEncoding.GetByteCount(state.DataSend.ToString());
state.Request.Method = "POST";
state.Request.ContentType = "application/soap+xml; charset=" + ContentEncoding.WebName.ToLower();
![](/Images/OutliningIndicators/InBlock.gif)
//开始获取请求流
state.Request.BeginGetRequestStream(new AsyncCallback(ReqCall), state);
![](/Images/OutliningIndicators/InBlock.gif)
//阻塞当前进程,直到收到完成的通知。
allDone.WaitOne();
}
catch (Exception ex)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
state.Error = ex;
allDone.Set();
}
finally
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
allDone.Reset();
}
![](/Images/OutliningIndicators/InBlock.gif)
string rData = null;
if (state.Error == null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(state.DataRecived.ToString());
rData = ResloveRecivedData(methodName, doc);
}
string sData = state.DataSend.ToString();
SoapInvokeCompleteArgs args = new SoapInvokeCompleteArgs(methodName,
sData,
rData,
state.Error);
//访问完成通知Soap完成事件。
OnSoapInvokeCompleted(args);
state.Close();
GC.WaitForPendingFinalizers();
GC.Collect();
}
![](/Images/OutliningIndicators/InBlock.gif)
private void ReqCall(IAsyncResult ar)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
RequestState state = (RequestState) ar.AsyncState;
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//写入请求
StreamWriter streamWriter = new StreamWriter(state.Request.EndGetRequestStream(ar));
streamWriter.Write(state.DataSend.ToString());
streamWriter.Flush();
streamWriter.Close();
![](/Images/OutliningIndicators/InBlock.gif)
//开始取得响应。
state.Request.BeginGetResponse(new AsyncCallback(ResCall), state);
}
catch (Exception ex)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
state.Error = ex;
allDone.Set();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
private void ResCall(IAsyncResult ar)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
RequestState state = (RequestState) ar.AsyncState;
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//取响应完毕。
state.Response = (HttpWebResponse) state.Request.EndGetResponse(ar);
state.ResponseStream = state.Response.GetResponseStream();
//开始读取流。
state.ResponseStream.BeginRead(state.BufferRead, 0, BUFFER_SIZE,
new AsyncCallback(ReadCall), state);
}
catch (Exception ex)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
state.Error = ex;
allDone.Set();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
private void ReadCall(IAsyncResult ar)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
RequestState state = (RequestState) ar.AsyncState;
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//分段读取流。
int read = state.ResponseStream.EndRead(ar);
if (read > 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string strRes = ContentEncoding.GetString(state.BufferRead, 0, read);
state.DataRecived.Append(strRes);
state.ResponseStream.BeginRead(state.BufferRead, 0, BUFFER_SIZE,
new AsyncCallback(ReadCall), state);
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
allDone.Set();
}
}
catch (Exception ex)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
state.Error = ex;
allDone.Set();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
同步方法#region 同步方法
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 同步调用webService的方法
/// </summary>
/// <param name="methodName">方法名称</param>
/// <param name="data">发送的xml数据</param>
/// <returns>返回的xml数据</returns>
public InvokeResult Invoke(string methodName, PostDataArray data)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
InvokeResult result = new InvokeResult();
result.MethodName = methodName;
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(ServiceUrl);
![](/Images/OutliningIndicators/InBlock.gif)
if (TimeOut > 0) request.Timeout = TimeOut;
if (Proxy != null) request.Proxy = Proxy;
if (Credentials != null) request.Credentials = Credentials;
![](/Images/OutliningIndicators/InBlock.gif)
result.DataSend = ResloveSendData(methodName, data);
request.ContentLength = ContentEncoding.GetByteCount(result.DataSend);
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=" + ContentEncoding.WebName.ToLower();
![](/Images/OutliningIndicators/InBlock.gif)
StreamWriter streamWriter = new StreamWriter(request.GetRequestStream());
streamWriter.Write(result.DataSend);
streamWriter.Flush();
streamWriter.Close();
![](/Images/OutliningIndicators/InBlock.gif)
HttpWebResponse response = null;
Stream responseStream = null;
try
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
response = (HttpWebResponse) request.GetResponse();
responseStream = response.GetResponseStream();
XmlDocument doc = new XmlDocument();
doc.Load(responseStream);
result.DataRecived = ResloveRecivedData(methodName, doc);
}
catch (Exception ex)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
result.Error = ex;
//AppNet.GetLog().wLog(ex.ToString(), "Exception at " + invokeMethod + " Invoke");
}
finally
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (response != null) response.Close();
if (responseStream != null) responseStream.Close();
GC.WaitForPendingFinalizers();
GC.Collect();
}
return result;
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
helper Method#region helper Method
![](/Images/OutliningIndicators/InBlock.gif)
//将发送的数据从PostDataArray转化成soap1.2的xml数据格式。
private string ResloveSendData(string invokeMethod, PostDataArray data)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string soapNs = "http://www.w3.org/2003/05/soap-envelope";
string strSoapData;
using (MemoryStream stream = new MemoryStream())
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
using (XmlTextWriter writer = new XmlTextWriter(stream, ContentEncoding))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
writer.WriteStartDocument();
writer.WriteStartElement("soap12", "Envelope", soapNs);
writer.WriteStartElement("soap12", "Body", soapNs);
writer.WriteStartElement(invokeMethod, Namespace);
AddData2XmlWriter(writer, data);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndElement();
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(stream))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
strSoapData = reader.ReadToEnd();
}
}
}
return strSoapData;
}
![](/Images/OutliningIndicators/InBlock.gif)
//我对返回的xml数据进行了简单的处理,仅留下了<方法名Result></方法名Result>这一节,以便后续处理。
private string ResloveRecivedData(string invokeMethod, XmlDocument doc)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
bool IsSoap12 = false;
if (doc.OuterXml.IndexOf("soap12:Envelope") != -1) IsSoap12 = true;
XmlNamespaceManager nsmanager = new XmlNamespaceManager(doc.NameTable);
if (IsSoap12)
nsmanager.AddNamespace("soap12", "http://www.w3.org/2003/05/soap-envelope");
else
nsmanager.AddNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");
string xpath = "//soap:Envelope/soap:Body";
if (IsSoap12) xpath = "//soap12:Envelope/soap12:Body";
XmlNode node = doc.SelectSingleNode(xpath, nsmanager);
string strDoc = node.InnerXml;
strDoc =
strDoc.Replace("<" + invokeMethod + "Response xmlns=\"" + Namespace + "\"",
"<" + invokeMethod + "Response");
doc = new XmlDocument();
doc.LoadXml(strDoc);
XmlNode rNode = doc.SelectSingleNode(invokeMethod + "Response");
strDoc = rNode.InnerXml;
return strDoc;
}
![](/Images/OutliningIndicators/InBlock.gif)
//添加PostDataArray到XmlWriter(这个方法为ResloveSendData服务)
private void AddData2XmlWriter(XmlWriter writer, PostDataArray datas)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (datas.ColName.Length > 0) writer.WriteStartElement(datas.ColName);
foreach (PostData d in datas)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
writer.WriteStartElement(d.Key);
if (d.Value.GetType() == typeof (byte[]))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
byte[] bt = (byte[]) d.Value;
writer.WriteBase64(bt, 0, bt.Length);
}
else
writer.WriteValue(d.Value);
writer.WriteEndElement();
}
![](/Images/OutliningIndicators/InBlock.gif)
if (datas.ColName.Length > 0) writer.WriteEndElement();
![](/Images/OutliningIndicators/InBlock.gif)
if (datas.Childs.Count > 0)
foreach (PostDataArray col in datas.Childs)
AddData2XmlWriter(writer, col);
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
这里是几个辅助类,自己去看看吧#region 这里是几个辅助类,自己去看看吧
![](/Images/OutliningIndicators/InBlock.gif)
//存储同步调用后的结果
internal struct InvokeResult
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public Exception Error;
public string DataRecived;
public string DataSend;
public string MethodName;
}
![](/Images/OutliningIndicators/InBlock.gif)
internal struct PostData
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public PostData(string key, object value)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Key = key;
Value = value;
}
![](/Images/OutliningIndicators/InBlock.gif)
public string Key;
public object Value;
}
![](/Images/OutliningIndicators/InBlock.gif)
internal class PostDataArray : CollectionBase
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public PostDataArray()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
dataCols = new List<PostDataArray>();
}
![](/Images/OutliningIndicators/InBlock.gif)
private List<PostDataArray> dataCols;
private string colN = "";
![](/Images/OutliningIndicators/InBlock.gif)
public string ColName
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return colN; }
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ colN = value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public PostData this[int index]
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return (PostData) List[index]; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public List<PostDataArray> Childs
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return dataCols; }
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Add(PostData obj)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
List.Add(obj);
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Add(string key, object value)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
List.Add(new PostData(key, value));
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Add(PostDataArray obj)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
dataCols.Add(obj);
}
![](/Images/OutliningIndicators/InBlock.gif)
public new void Clear()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
base.Clear();
dataCols.Clear();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
internal class RequestState
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public const int BUFFER_SIZE = 512;
public byte[] BufferRead;
public HttpWebRequest Request;
public HttpWebResponse Response;
public Stream ResponseStream;
public Stream RequestStream;
public string MethodName;
public PostDataArray Parameters;
public StringBuilder DataSend;
public StringBuilder DataRecived;
public Exception Error;
![](/Images/OutliningIndicators/InBlock.gif)
public RequestState()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
BufferRead = new byte[BUFFER_SIZE];
DataRecived = new StringBuilder();
DataSend = new StringBuilder();
Request = null;
ResponseStream = null;
RequestStream = null;
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Close()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (ResponseStream != null) ResponseStream.Close();
if (Response != null) Response.Close();
if (Request != null) Request.Abort();
Response = null;
Request = null;
ResponseStream = null;
RequestStream = null;
DataRecived = null;
DataSend = null;
MethodName = null;
Parameters = null;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
//储存事件通知结果
internal struct SoapInvokeCompleteArgs
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public SoapInvokeCompleteArgs(Exception ex)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MethodName = null;
Error = ex;
DataSend = null;
DataRecived = null;
IsCompleted = true;
}
![](/Images/OutliningIndicators/InBlock.gif)
public SoapInvokeCompleteArgs(string data, string methodname)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MethodName = methodname;
Error = null;
DataSend = null;
DataRecived = data;
IsCompleted = true;
}
![](/Images/OutliningIndicators/InBlock.gif)
public SoapInvokeCompleteArgs(string methodname, string sendData, string recivedData, Exception error)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MethodName = methodname;
DataSend = sendData;
DataRecived = recivedData;
Error = error;
IsCompleted = true;
}
![](/Images/OutliningIndicators/InBlock.gif)
//调用的方法名称
public string MethodName;
//返回的xml数据
public string DataRecived;
//发送给weService的xml数据
public string DataSend;
//调用过程的错误信息
public Exception Error;
//是否已完成
public bool IsCompleted;
}
![](/Images/OutliningIndicators/InBlock.gif)
//委托完成事件
internal delegate void SoapInvokeCompletedEventHandler(object sender, SoapInvokeCompleteArgs e);
![](/Images/OutliningIndicators/InBlock.gif)
}代码说明:
代码原理比较简单,主要是了解Soap1.2的格式和xml操作。
已经在代码中加入了部分注释。下面是一个调用例子
void getwebservice(){
PostDataArray data = new PostDataArray();
data.Add("参数1", "参数值1");
PostDataArray indata = new PostDataArray();
indata.Add("嵌套参数1","嵌套参数值1");
indata.ColName = "嵌套节点名称";
data.Add(indata);
SoapClient soap = new SoapClient();
soap.ContentEncoding = Encoding.GetEncoding(65001);
soap.Proxy = new WebProxy("代理");
soap.ServiceUrl = new Uri("webService地址");
soap.TimeOut = 180000;//超时时间(毫秒)
//用同步方法调用ws,直接返回InvokeResult结果;
soap.Invoke("webService方法名称", data);
//用异步方法调用ws,在SoapInvokeCompleted事件中处理结果。
soap.SoapInvokeCompleted
+= new SoapInvokeCompletedEventHandler(soap_SoapInvokeCompleted);
soap.InvokeAsync("webService方法名称", data);
}