一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

asp.net中 GET/POST/SOAP方式调用WebService实现方法

时间:2012-09-05 编辑:简简单单 来源:一聚教程网

GET与POST区别
HTTP 定义了与服务器交互的不同方法,最基本的方法是 GET 和 POST(Ajax开发,关心的只有GET请求和POST请求)。

GET与POST方法有以下区别:

(1)   在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。

(2)   GET方式提交的数据最多只能有1024字节,而POST则没有此限制。

(3)   安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。

(4)   安全的和幂等的。所谓安全的意味着该操作用于获取信息而非修改信息。幂等的意味着对同一 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。换句话说,GET 请求一般不应产生副作用。从根本上讲,其目标是当用户打开一个链接时,她可以确信从自身的角度来看没有改变资源。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。反之亦然。POST 请求就不那么轻松了。POST 表示可能改变服务器上的资源的请求。仍然以新闻站点为例,读者对文章的注解应该通过 POST 请求实现,因为在注解提交之后站点已经不同了。

 代码如下 复制代码
using System;   
using System.Web;   
using System.Xml;   
using System.Collections;   
using System.Net;   
using System.Text;   
using System.IO;   
using System.Xml.Serialization;   
    
///    
///  利用WebRequest/WebResponse进行WebService调用的类   
///
   
public class WebSvcCaller   
{   
    //   
    //     
    //       
    //       
    // 
   
    //
   
    private static Hashtable _xmlNamespaces = new Hashtable();//缓存xmlNamespace,避免重复调用GetNamespace   
    ///    
    /// 需要WebService支持Post调用   
    ///
   
    public static XmlDocument QueryPostWebService(String URL, String MethodName, Hashtable Pars)   
    {   
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName);   
        request.Method = "POST";   
        request.ContentType = "application/x-www-form-urlencoded";   
        SetWebRequest(request);   
        byte[] data = EncodePars(Pars);   
        WriteRequestData(request, data);   
        return ReadXmlResponse(request.GetResponse());   
    }   
      
    ///    
    /// 需要WebService支持Get调用   
    ///
   
    public static XmlDocument QueryGetWebService(String URL, String MethodName, Hashtable Pars)   
    {   
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName + "?" + ParsToString(Pars));   
        request.Method = "GET";   
        request.ContentType = "application/x-www-form-urlencoded";   
        SetWebRequest(request);   
        return ReadXmlResponse(request.GetResponse());   
    }   
  
      
    ///    
    /// 通用WebService调用(Soap),参数Pars为String类型的参数名、参数值   
    ///
   
    public static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars)   
    {   
        if (_xmlNamespaces.ContainsKey(URL))   
        {   
            return QuerySoapWebService(URL, MethodName, Pars, _xmlNamespaces[URL].ToString());   
        }   
        else  
        {   
            return QuerySoapWebService(URL, MethodName, Pars, GetNamespace(URL));   
        }   
    }   
    private static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars, string XmlNs)   
    {       
        _xmlNamespaces[URL] = XmlNs;//加入缓存,提高效率   
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);   
        request.Method = "POST";   
        request.ContentType = "text/xml; charset=utf-8";   
        request.Headers.Add("SOAPAction", """ + XmlNs + (XmlNs.EndsWith("/") ? "" : "/") + MethodName + """);   
        SetWebRequest(request);   
        byte[] data = EncodeParsToSoap(Pars, XmlNs, MethodName);   
        WriteRequestData(request, data);   
        XmlDocument doc = new XmlDocument(), doc2 = new XmlDocument();   
        doc = ReadXmlResponse(request.GetResponse());   
        XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);   
        mgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");   
        String RetXml = doc.SelectSingleNode("//soap:Body/*/*", mgr).InnerXml;   
        doc2.LoadXml("" + RetXml + "");   
        AddDelaration(doc2);   
        return doc2;   
    }   
    private static string GetNamespace(String URL)   
    {   
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "?WSDL");   
        SetWebRequest(request);   
        WebResponse response = request.GetResponse();   
        StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);   
        XmlDocument doc = new XmlDocument();   
        doc.LoadXml(sr.ReadToEnd());   
        sr.Close();   
        return doc.SelectSingleNode("//@targetNamespace").Value;   
    }   
    private static byte[] EncodeParsToSoap(Hashtable Pars, String XmlNs, String MethodName)   
    {   
        XmlDocument doc = new XmlDocument();   
        doc.LoadXml("");   
        AddDelaration(doc);   
        XmlElement soapBody = doc.createElement_x_x("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");   
        XmlElement soapMethod = doc.createElement_x_x(MethodName);   
        soapMethod.SetAttribute("xmlns", XmlNs);   
        foreach (string k in Pars.Keys)   
        {   
            XmlElement soapPar = doc.createElement_x_x(k);   
            soapPar.InnerXml = ObjectToSoapXml(Pars[k]);   
            soapMethod.AppendChild(soapPar);   
        }   
        soapBody.AppendChild(soapMethod);   
        doc.DocumentElement.AppendChild(soapBody);   
        return Encoding.UTF8.GetBytes(doc.OuterXml);   
    }   
    private static string ObjectToSoapXml(object o)   
    {   
        XmlSerializer mySerializer = new XmlSerializer(o.GetType());   
        MemoryStream ms = new MemoryStream();   
        mySerializer.Serialize(ms, o);   
        XmlDocument doc = new XmlDocument();   
        doc.LoadXml(Encoding.UTF8.GetString(ms.ToArray()));   
        if (doc.DocumentElement != null)   
        {   
            return doc.DocumentElement.InnerXml;   
        }   
        else  
        {   
            return o.ToString();   
        }   
    }   
    private static void SetWebRequest(HttpWebRequest request)   
    {   
        request.Credentials = CredentialCache.DefaultCredentials;   
        request.Timeout = 10000;   
    }   
    private static void WriteRequestData(HttpWebRequest request, byte[] data)   
    {   
        request.ContentLength = data.Length;   
        Stream writer = request.GetRequestStream();   
        writer.Write(data, 0, data.Length);   
        writer.Close();   
    }   
    private static byte[] EncodePars(Hashtable Pars)   
    {   
        return Encoding.UTF8.GetBytes(ParsToString(Pars));   
    }   
    private static String ParsToString(Hashtable Pars)   
    {   
        StringBuilder sb = new StringBuilder();   
        foreach (string k in Pars.Keys)   
        {   
            if (sb.Length > 0)   
            {   
                sb.Append("&");   
            }   
            //sb.Append(HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(Pars[k].ToString()));   
        }   
        return sb.ToString();   
    }   
    private static XmlDocument ReadXmlResponse(WebResponse response)   
    {   
        StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);   
        String retXml = sr.ReadToEnd();   
        sr.Close();   
        XmlDocument doc = new XmlDocument();   
        doc.LoadXml(retXml);   
        return doc;   
    }   
    private static void AddDelaration(XmlDocument doc)   
    {   
        XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null);   
        doc.InsertBefore(decl, doc.DocumentElement);   
    }   

  

调用示例:

 代码如下 复制代码

Hashtable ht = new Hashtable();   
ht.Add("str", "test");   
ht.Add("b", "true");   
XmlDocument xx = WebSvcCaller.QuerySoapWebService("http://localhost:81/service.asmx", "HelloWorld", ht);   
MessageBox.Show(xx.OuterXml);   

这个类有三个公用的方法:QuerySoapWebService为通用的采用Soap方式调用WebService,QueryGetWebService采用GET方式调用,QueryPostWebService采用POST方式调用,后两个方法需要WebService服务器支持相应的调用方式。三个方法的参数和返回值相同:URL为Webservice的Url地址(以.asmx结尾的);MethodName为要调用的方法名称;Pars为参数表,它的Key为参数名称,Value为要传递的参数的值,Value可为任意对象,前提是这个对象可以被xml序列化。注意方法名称、参数名称、参数个数必须完全匹配才能正确调用。第一次以Soap方式调用时,因为需要查询WSDL获取xmlns,因此需要时间相对长些,第二次调用不用再读WSDL,直接从缓存读取。这三个方法的返回值均为XmlDocument对象,这个返回的对象可以进行各种灵活的操作。最常用的一个SelectSingleNode方法,可以让你一步定位到Xml的任何节点,再读取它的文本或属性。也可以直接调用Save保存到磁盘。采用Soap方式调用时,根结点名称固定为root。

这个类主要是利用了WebRequest/WebResponse来完成各种网络查询操作。为了精简明了,这个类中没有添加错误处理,需要在调用的地方设置异常捕获。
下面是一个调用实例:

 代码如下 复制代码
protected void Page_Load(object sender , EventArgs e)   
    ...{   
        try  
        ...{   
            Hashtable pars = new Hashtable();   
            String Url = "http://www.260dns.cn/Services/Weather.asmx";   
            pars["city"] = "上海";   
            pars["wdate"]="2008-3-19";   
            XmlDocument doc = WebSvcCaller.QuerySoapWebService(Url , "GetWeather" , pars);   
            Response.Write(doc.OuterXml);   
        }   
        catch (Exception ex)   
        ...{   
            Response.Write(ex.Message);   
        }   
    }   

热门栏目