zoukankan      html  css  js  c++  java
  • 访问WebService

    访问WebService的方法有3大种:

    1.       通过HttpGetPost方法

    2.       通过SOAP

    3.       .net的代理类

    第一种只能访问本机的,后二种可以访问任何地方的。

    使用最方便,编码量最少,且可配置性也较好的是第三种,所以应尽可能多的使用第三种,其代码就是实例化一个对象,然后调用其方法即可。

    有时候(比如在开发阶段不知道要访问哪个服务)需要用前2种方式,因为第一种有只能访问本机的限制,所以不推荐使用,一般应用第二种,即SOAP方式,它也是WebService标准的交互协议,其实就是基于Http协议之上,对输入和输出参数的字符串格式的规定。

    SOAP又分为1.11.2两种,它们的区别仅限于XML编码和TagName,调用过程没有区别,都是基于HttpPost,拿1.1为例:

    1.       首先通过在浏览器里输入http://domain/ServiceName.asmx?op=FunName 查看其输入和输出的样例(里面有1.11.2两种)。

    2.       用服务地址(如http://domain/ServiceName.asmx )实例化一个HttpWebRequest类,然后设置其方法名(SOAPAction, ContentType等属性

    3.       发出调用请求(即把SOAP消息写入到请求流)。

    4.       接收响应(是一个XmlDocument对象)。

    代码如下:

            public static XmlDocument CallWebServiceBySoap(string serviceUrl, string argString)

            {

                // For example: serviceUrl = "http://localhost:2258/ComplexService.asmx?"

                // argString = "op=DoSomething&input=<a>1</a><b>2</b>"

                // op is function name

                try

                {

                    //return QueryPostWebService(serviceUrl, Encoding.UTF8.GetBytes(argString));

                    char[] sepKey = "&".ToCharArray();

                    char[] sepValue = "=".ToCharArray();

                    string[] pas = argString.Split(sepKey);

                    StringBuilder sb = new StringBuilder();

                    string funName = null;

                    foreach (string pa in pas)

                    {

                        string[] ps = pa.Split(sepValue);

                        if (ps[0] == "op")

                        {

                            funName = ps[1];

                        }

                        else

                        {

                            sb.Append("<" + ps[0] + ">");

                            sb.Append(ps[1]);

                            sb.Append("</" + ps[0] + ">");

                        }

                    }

                    string soapFmt =

        @"<?xml version=""1.0"" encoding=""utf-8""?>

    <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:Body>

        <{0} xmlns=""http://tempuri.org/"">

          {1}

        </{0}>

      </soap:Body>

    </soap:Envelope>";

                    string soap = string.Format(soapFmt, funName, sb.ToString());

                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(serviceUrl);

                    req.Headers.Add("SOAPAction", string.Format("\"http://tempuri.org/{0}\"", funName));

                    req.ContentType = "text/xml;charset=\"utf-8\"";

                    req.Accept = "text/xml";

                    req.Method = "POST";

                    using (Stream stm = req.GetRequestStream())

                    {

                        using (StreamWriter stmw = new StreamWriter(stm))

                        {

                            stmw.Write(soap);

                        }

                    }

                    WebResponse response = req.GetResponse();

                    //Stream responseStream = response.GetResponseStream();

                    XmlDocument doc = ReadXmlResponse(response);

                    return doc;

                }

                catch

                {

                    //EntLibLogger.LogCriticalException(

                    //    string.Format("Web Service error: url = {0}, args = {1}"

                    //    , serviceUrl, argString));

                    throw;

                }

            }

           

    参数部分需要有一定的构成格式,我封装了一个较通用的单参数(简单类型(如int,string)的参数不必用此,直接拼字符串即可,此处是为复杂类型设计的)示例(可以作为进一步扩展的基础,用于我们未来的的访问Web服务的项目),多参数可以进一步将最后2个参数改进为Dictionary

            private T GetFromWebServiceBySoap<T>(string serviceUrl, string funName, string inputParaName, object input)

            {

                // Prepare Input

                string inputStr = ObjectSerializer.Serialize(input);

                XmlDocument docInput = new XmlDocument();

                docInput.LoadXml(inputStr);

                string inputXml = docInput.DocumentElement.InnerXml;

                string argString = string.Format("op={0}&{1}={2}", funName, inputParaName, inputXml);

                // Call & Get Result XmlDocument

                XmlDocument docResult;

                docResult = WebServiceAccess.CallWebServiceBySoap(serviceUrl, argString);

                // DeSerialize to Result Object

                Type resultType = typeof(T);

                string objStr = docResult.DocumentElement.ChildNodes[0].ChildNodes[0].ChildNodes[0].OuterXml;

                string tagName = docResult.DocumentElement.ChildNodes[0].ChildNodes[0].ChildNodes[0].Name;

                objStr = objStr.Replace("<" + tagName, "<" + resultType.Name);

                objStr = objStr.Replace("</" + tagName, "</" + resultType.Name);

                docResult.LoadXml(objStr);

                docResult.LoadXml(docResult.OuterXml.Replace(docResult.DocumentElement.NamespaceURI, ""));

                docResult.DocumentElement.RemoveAllAttributes();

                objStr = docResult.OuterXml;

                T result

                    = ObjectSerializer.DeSerializerString2Object<T>(objStr);

                // Return Result

                return result;

            }

    工具类:

    public static class ObjectSerializer

        {

            public static string Serialize(object objToXml)

            {

                if (objToXml == null)

                    throw new ArgumentNullException("objToXml");

                XmlSerializer serializer;

                XmlSerializerNamespaces xsn;

                StringWriter writer;

                serializer = new XmlSerializer(objToXml.GetType());

                xsn = new XmlSerializerNamespaces();

                xsn.Add(String.Empty, String.Empty);

                writer = new StringWriter();

                serializer.Serialize(writer, objToXml, xsn);

                return writer.GetStringBuilder().ToString();

            }

            public static T DeSerializerString2Object<T>(string sXml)

            {

                if (sXml == null)

                    throw new ArgumentNullException("sXml");

                XmlReader reader = XmlReader.Create(new StringReader(sXml));

                XmlSerializer serializer = new XmlSerializer(typeof(T));

                object obj = serializer.Deserialize(reader);

                return (T)obj;

            }

        }

     

    调用示例:

    protected void Button2_Click(object sender, EventArgs e)

            {

                TestEntities.ComplexInput input = new TestEntities.ComplexInput();

                input.a = 1;

                input.b = 2;

                string serviceUrl = "http://localhost:2258/ComplexService.asmx";

                TestEntities.ComplexResult complexResult

                    = GetFromWebServiceBySoap<TestEntities.ComplexResult>(serviceUrl, "DoSomething", "input", input);

                lblMsg.Text = "complexResult.x = " + complexResult.x.ToString();

            }

    其中输入和输出参数的类定义为:

    public class ComplexInput

        {

            public int a;

            public int b;

        }

    public class ComplexResult

        {

            public int x;

        }

    Web服务代码为:

    public class ComplexService : System.Web.Services.WebService

        {

            [WebMethod]

            public ComplexResult DoSomething(ComplexInput input)

            {

                ComplexResult complexResult = new ComplexResult();

                complexResult.x = input.a + input.b;

                return complexResult;

            }

    }

  • 相关阅读:
    分布式共识协议RAFT基本原理
    slave_net_timeout, MASTER_HEARTBEAT_PERIOD, MASTER_CONNECT_RETRY,以及 MASTER_RETRY_COUNT设置和查看
    单例模式
    截取字符串Java
    Hibernate+struts+JqueryAjax+jSON实现无刷新三级联动
    数组集合区别
    Android Activity生命周期(图文)!
    Activity的生命周期
    Android四大组件
    各种时间获取 .net
  • 原文地址:https://www.cnblogs.com/bighuiwolf/p/1771275.html
Copyright © 2011-2022 走看看