1. 程式人生 > >C# webService呼叫方式-程式碼直接呼叫

C# webService呼叫方式-程式碼直接呼叫

最近和用友做對接,那邊用java 寫的一個基於soap 協議的web服務端。由於以前呼叫使用的是 引用wsdl 檔案的方式直接生成 webService 呼叫類,可是現在wsdl 檔案死活都引用不成功,然後給用友那邊溝通,人家說沒有問題,沒辦法人家是大爺,問題總得解決吧。好廢話不多說,直接乾貨。

引用 wsdl 檔案報的錯誤 和圖片

URI file:///E:/專案/2018開發/介面說明/wb.wsdl 處的文件未被識別為已知的文件型別。
來自各已知型別的錯誤資訊可能有助於修復該問題:
- 來自“XML 架構”的報告是“W3C XML 架構的根元素應為 <schema>,名稱空間應為“http://www.w3.org/2001/XMLSchema”。”。
- 來自“DISCO 文件”的報告是“在 URL file:///E:/專案/2018開發/14.晨光生物介面說明/wb.wsdl 處找不到發現文件。”。
  - 無法識別此文件格式。
- 來自“WSDL 文件”的報告是“XML 文件(59, 5)中

解決方法:不引用wsdl 檔案,直接通過http 請求的方式去呼叫服務

 public  class WebServiceCall
    {
        public static string mUrl = string.Empty;
        public WebServiceCall(string url)
        {
            mUrl = url;
        }

        /// <summary>
        /// 呼叫介面
        /// </summary>
        /// <param name="methodName">方法名稱</param>
        /// <param name="param">引數名稱</param>
        /// <returns>返回值</returns>
        public string callWebService(string methodName,Dictionary<string,string> param)
        {
            ///獲取請求資料
            byte[] data = getRequestDataJava(methodName, param); // getRequestData(methodName, param);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(mUrl);
            request.Method = "POST";
            request.ContentType = "text/xml; charset=utf-8";
            string  mSoapAction = "http://tempuri.org/" + methodName;
            request.Headers.Add("SOAPAction", mSoapAction);
            request.ContentLength = data.Length;
            Stream rStream = request.GetRequestStream();
            rStream.Write(data,0,data.Length);
            rStream.Close();
           
            WebResponse response = request.GetResponse();
            Stream dataStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string result = reader.ReadToEnd();
            
            dataStream.Close();
            response.Close();
            return result;
        }


        /// <summary>
        /// 獲取請求內容(方法1) 適合 .Net
        /// </summary>
        /// <param name="methodName">方法名稱</param>
        /// <param name="param">引數</param>
        /// <returns></returns>
        public byte[] getRequestData(string methodName,Dictionary<string,string> param)
        {
            StringBuilder requestData = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
                .Append("<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/\">")
                .Append("  <soap:Body>")
                .Append("<").Append(methodName)
                .Append(" xmlns=\"http://tempuri.org/\">");
            foreach (KeyValuePair<string, string> item in param)
            {
                requestData.Append("<").Append(item.Key).Append(">")
                .Append(item.Value)
                .Append("</").Append(item.Key).Append(">");
            }
            requestData.Append("</").Append(methodName).Append(">")
            .Append("</soap:Body>")
            .Append("</soap:Envelope>");
            string val = requestData.ToString();
           byte[] data = Encoding.UTF8.GetBytes(val);
           return data;
        }

        /// <summary>
        /// 獲取資料(方法2) 相容所有的(java soap 服務端和.net  soap 服務端)
        /// </summary>
        /// <param name="methodName">方法名稱</param>
        /// <param name="param">引數</param>
        /// <returns></returns>
        public byte[] getRequestDataALL(string methodName,Dictionary<string,string>param)
        {
            StringBuilder requestBuider= new StringBuilder();
            requestBuider.Append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:icc=\"http://pub.ccgb.so.itf.nc/ICCGBHAService\">");
            requestBuider.Append("<soapenv:Header/>");
            requestBuider.Append("<soapenv:Body>");
            requestBuider.Append("<icc:").Append(methodName).Append(">");
            foreach (KeyValuePair<string, string> item in param)
            {
                requestBuider.Append("<").Append(item.Key).Append(">");
                requestBuider.Append(item.Value);
                requestBuider.Append("</").Append(item.Key).Append(">");
            }
            requestBuider.Append("</icc:").Append(methodName).Append(">");
            requestBuider.Append("</soapenv:Body>");
            requestBuider.Append("</soapenv:Envelope>");
            string val = requestBuider.ToString();
            byte[] data = Encoding.UTF8.GetBytes(val);
            return data;
        }
    }
 

生成請求引數函式有兩個getRequestData和getRequestDataALL,  一個是 soapenv:Envelope,一個是soap:Envelope ,不知道兩個有什麼不同,可是呼叫的時候 soapenv:Envelope 相容所有的 .Net 和java 開發的soap 服務端,而 soap:Envelope 只相容 .net 的服務端,而呼叫java 卻報 伺服器內部錯誤500,由於服務端是用友開發的也沒法進一步查詢該問題。都是基於soap 協議的為什麼標準不同,百度了一下也沒有找到像樣的結果,希望高手指點一下