最近和用友做对接,那边用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 协议的为什么标准不同,百度了一下也没有找到像样的结果,希望高手指点一下