C# webService调用方式-代码直接调用

时间:2024-03-31 16:36:49

最近和用友做对接,那边用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)中

C# webService调用方式-代码直接调用

解决方法:不引用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 协议的为什么标准不同,百度了一下也没有找到像样的结果,希望高手指点一下