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 協議的為什麼標準不同,百度了一下也沒有找到像樣的結果,希望高手指點一下