asp.net访问WebService的各种方式

WebService的访问形式主要有:SOAP调用、XMLHTTP POST、GET调用、MicroSoft.XMLDOMC调用、webbehavior.htc调用

我们知道的在C#后台本地调用Webservice最简单、快捷的调用WebService的方法即通过鼠标手动添加web服务引用的方式。实际操作中我们会使用到另外一种方式,即通过HttpWebRequest构造请求。这种方式下以Post和Get两种请求为主,另外还有通用方式调用。一共三种。下面我们来看实际操作的实现方法。

由于这三种方式在实现原理上是相似的。只是具体的方式不同(哈哈,我的表述不是很专业,能理解是怎么回事就行)。于是我们抽象出公共的基类:WebServiceCaller

/// <summary>

/// 访问webservice基类

/// </summary>

public abstract class WebServiceCaller

{

    /// <summary>

    /// 请求WebService

    /// </summary>

    /// <param name="URL">WebService的路径</param>

    /// <param name="MethodName">方法名</param>

    /// <param name="Pars">参数</param>

    /// <returns></returns>

    abstract public System.Xml.XmlDocument RequestWebService(ResquestParams rp);



    /// <summary>

    /// 设置凭证与超时时间

    /// </summary>

    /// <param name="request"></param>

    public static void SetWebRequest(HttpWebRequest request)

    {

        request.Credentials = CredentialCache.DefaultCredentials;

        request.Timeout = 10000;

    }



    /// <summary>

    /// 读取响应输出流

    /// </summary>

    /// <param name="response"></param>

    /// <returns></returns>

    public 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;

    }



    public 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();

    }

}
View Code

Post方式调用Webservice类的实现代码:

/// <summary>

/// Post方式访问

/// </summary>

public class WebServiceCallerByPost : WebServiceCaller

{

    public override XmlDocument RequestWebService(ResquestParams rp)

    {

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(rp.URL + "/" + rp.MethodName);

        request.Method = "POST";

        request.ContentType = "application/x-www-form-urlencoded";

        SetWebRequest(request);

        byte[] data = EncodePars(rp.Parames);

        WriteRequestData(request, data);

        return ReadXmlResponse(request.GetResponse());

    }



    /// <summary>

    /// 参数编码

    /// </summary>

    /// <param name="Pars"></param>

    /// <returns></returns>

    private static byte[] EncodePars(Hashtable Pars)

    {

        return Encoding.UTF8.GetBytes(ParsToString(Pars));

    }



    /// <summary>

    /// 添加请求参数

    /// </summary>

    /// <param name="request"></param>

    /// <param name="data"></param>

    private static void WriteRequestData(HttpWebRequest request, byte[] data)

    {

        request.ContentLength = data.Length;

        System.IO.Stream writer = request.GetRequestStream();

        writer.Write(data, 0, data.Length);

        writer.Close();

    }



}
View Code

Get方式调用Webservice类的实现代码:

/// <summary>

/// Get方式访问

/// </summary>

public class WebServiceCallerByGet : WebServiceCaller

{

    public override XmlDocument RequestWebService(ResquestParams rp)

    {

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(rp.URL + "/" + rp.MethodName + "?" + ParsToString(rp.Parames));

        request.Method = "GET";

        request.ContentType = "application/x-www-form-urlencoded";

        SetWebRequest(request);

        return ReadXmlResponse(request.GetResponse());

    }

}
View Code

通用方式调用Webservice类的实现代码:

/// <summary>

/// 通用方式调用webservice

/// </summary>

public class SoapWebService : WebServiceCaller

{



    public override XmlDocument RequestWebService(ResquestParams rp)

    {

        if (_xmlNamespaces.ContainsKey(rp.URL))

        {

            return QuerySoapWebService(rp.URL, rp.MethodName, rp.Parames, _xmlNamespaces[rp.URL].ToString());

        }

        else

        {

            return QuerySoapWebService(rp.URL, rp.MethodName, rp.Parames, GetNamespace(rp.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("<root>" + RetXml + "</root>");



        AddDelaration(doc2);



        return doc2;

    }



    private static string GetNamespace(String URL)

    {

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "?WSDL");

        SetWebRequest(request);

        WebResponse response = request.GetResponse();

        System.IO.StreamReader sr = new System.IO.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("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"></soap:Envelope>");

        AddDelaration(doc);

        //XmlElement soapBody = doc.createElement_x_x("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");

        XmlElement soapBody = doc.CreateElement("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");

        //XmlElement soapMethod = doc.createElement_x_x(MethodName);

        XmlElement soapMethod = doc.CreateElement(MethodName);

        soapMethod.SetAttribute("xmlns", XmlNs);

        foreach (string k in Pars.Keys)

        {

            //XmlElement soapPar = doc.createElement_x_x(k);

            XmlElement soapPar = doc.CreateElement(k);

            soapPar.InnerXml = ObjectToSoapXml(Pars[k]);

            soapMethod.AppendChild(soapPar);

        }

        soapBody.AppendChild(soapMethod);

        doc.DocumentElement.AppendChild(soapBody);

        return Encoding.UTF8.GetBytes(doc.OuterXml);

    }



    private static void WriteRequestData(HttpWebRequest request, byte[] data)

    {

        request.ContentLength = data.Length;

        System.IO.Stream writer = request.GetRequestStream();

        writer.Write(data, 0, data.Length);

        writer.Close();

    }



    private static void AddDelaration(XmlDocument doc)

    {

        XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null);

        doc.InsertBefore(decl, doc.DocumentElement);

    }



    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 Hashtable _xmlNamespaces = new Hashtable();//缓存xmlNamespace,避免重复调用GetNamespace
View Code

在编码调用时可以考虑设计一个请求参数类

public class ResquestParams

{

    /// <summary>

    /// WebService地址

    /// </summary>

    public string URL { get; set; }

    /// <summary>

    /// web方法

    /// </summary>

    public string MethodName { get; set; }

    /// <summary>

    /// 方法参数

    /// </summary>

    public Hashtable Parames { get; set; }

}
View Code

另外我们在aspx前台页面也会通过js代码来调用Webservice。此处略带"串烧"一下

$.post():

$(document).ready(function () {

    $("#btnRequest").click(function () {

        $.ajax({

            type: "post",

            contentType: "application/json",

            url: "http://localhost:5158/TestWebService.asmx/Add",

            data: "{m:12,n:2}", //注意区别于get方式的参数格式

            datatype: "json",

            error: function (x, e) {

                alert(x.responseText);

            },

            success: function (result) {

                alert(result.d);

            }

        });

    });

});
View Code

$.get():

$(document).ready(function () {

    $("#btnRequest").click(function () {

        $.ajax({

            type: "get",

            contentType: "application/json",

            url: "http://localhost:5158/TestWebService.asmx/Add",

            data: {'m':'12','n':'2'},

            datatype: "json",

            error: function (x, e) {

                alert(x.responseText);

            },

            success: function (result) {

                alert(result.d);

            }

        });

    });

});
View Code

注1:如果采用以上HTTP GET方式在后台访问WebService总是报500异常的话,那么很可能是你需要在WebService所在的站点下的配置文件中加上如下配置:

<webServices> 

   <protocols> 

       <add name= "HttpPost " /> 

       <add name= "HttpGet " /> 

    </protocols> 

</webServices>
View Code

注2:如果以上通过ajax.get()方式访问WebService时候提示这样的错误:尝试使用GET请求调用方法xx,但是不允许这样做。那么就是所调用的方法不支持脚本通过GET方式调用,需要在所调用的方法加上[ScriptMethod(UseHttpGet=true)]就ok了。

这里仅仅介绍如何消费WebService,其实要完整地学习它,我们还要了解它的历史沿革。好了就介绍到这儿。

你可能感兴趣的:(webservice)