代码之家  ›  专栏  ›  技术社区  ›  MaLKaV_eS

如何在.net中调用没有wsdl的web服务

  •  22
  • MaLKaV_eS  · 技术社区  · 16 年前

    我必须连接到不提供wsdl或asmx的第三方web服务。该服务的url仅为 http://server/service.soap

    this article

    此外,我要求提供wsdl文件,但被告知没有(而且不会有)。

    我正在使用C#with.NET2.0,无法升级到3.5(因此还没有WCF)。我认为第三方正在使用java,这就是他们提供的示例。

    提前谢谢!

    更新

    <SOAP-ENV:Envelope>
    <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
    <faultcode>SOAP-ENV:Server</faultcode>
    <faultstring>
    Cannot find a Body tag in the enveloppe
    </faultstring>
    </SOAP-ENV:Fault>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    
    5 回复  |  直到 16 年前
        1
  •  26
  •   Kiquenet user385990    7 年前

    首先,我们创建一个HttpWebRequest:

    public static HttpWebRequest CreateWebRequest(string url)
    {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
        webRequest.Headers.Add("SOAP:Action");
        webRequest.ContentType = "text/xml;charset=\"utf-8\"";
        webRequest.Accept = "text/xml";
        webRequest.Method = "POST";
        return webRequest;
    }
    

    public static XmlDocument ServiceCall(string url, int service, StringDictionary data)
    {
        HttpWebRequest request = CreateWebRequest(url);
    
        XmlDocument soapEnvelopeXml = GetSoapXml(service, data);
    
        using (Stream stream = request.GetRequestStream())
        {
            soapEnvelopeXml.Save(stream);
        }
    
        IAsyncResult asyncResult = request.BeginGetResponse(null, null);
    
        asyncResult.AsyncWaitHandle.WaitOne();
    
        string soapResult;
        using (WebResponse webResponse = request.EndGetResponse(asyncResult))
        using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
        {
            soapResult = rd.ReadToEnd();
        }
    
        File.WriteAllText(HttpContext.Current.Server.MapPath("/servicios/" + DateTime.Now.Ticks.ToString() + "assor_r" + service.ToString() + ".xml"), soapResult);
    
        XmlDocument resp = new XmlDocument();
    
        resp.LoadXml(soapResult);
    
        return resp;
    }
    

    就这些。如果有人认为必须在答案中添加GetSoapXml,我会把它写下来。

        2
  •  16
  •   John Saunders    10 年前

    必须 软盘 拇指驱动!

    如果您有任何能力向这项服务的提供商投诉,那么我敦促您这样做。如果你有推回的能力,那么就这样做。理想情况下,切换服务提供者,并告诉这些人这是因为他们没有提供WSDL。至少,找出他们认为这不重要的原因。

        3
  •  5
  •   Andrej Benedik    10 年前

    我已经创建了以下帮助器方法来手动调用WebService,无需任何引用:

    public static HttpStatusCode CallWebService(string webWebServiceUrl, 
                                                string webServiceNamespace, 
                                                string methodName, 
                                                Dictionary<string, string> parameters, 
                                                out string responseText)
    {
        const string soapTemplate = 
    @"<?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://www.w3.org/2003/05/soap-envelope"">
      <soap:Body>
        <{0} xmlns=""{1}"">
          {2}    </{0}>
      </soap:Body>
    </soap:Envelope>";
    
        var req = (HttpWebRequest)WebRequest.Create(webWebServiceUrl);
        req.ContentType = "application/soap+xml;";
        req.Method = "POST";
    
        string parametersText;
    
        if (parameters != null && parameters.Count > 0)
        {
            var sb = new StringBuilder();
            foreach (var oneParameter in parameters)
                sb.AppendFormat("  <{0}>{1}</{0}>\r\n", oneParameter.Key, oneParameter.Value);
    
            parametersText = sb.ToString();
        }
        else
        {
            parametersText = "";
        }
    
        string soapText = string.Format(soapTemplate, methodName, webServiceNamespace, parametersText);
    
    
        using (Stream stm = req.GetRequestStream())
        {
            using (var stmw = new StreamWriter(stm))
            {
                stmw.Write(soapText);
            }
        }
    
        var responseHttpStatusCode = HttpStatusCode.Unused;
        responseText = null;
    
        using (var response = (HttpWebResponse)req.GetResponse())
        {
            responseHttpStatusCode = response.StatusCode;
    
            if (responseHttpStatusCode == HttpStatusCode.OK)
            {
                int contentLength = (int)response.ContentLength;
    
                if (contentLength > 0)
                {
                    int readBytes = 0;
                    int bytesToRead = contentLength;
                    byte[] resultBytes = new byte[contentLength];
    
                    using (var responseStream = response.GetResponseStream())
                    {
                        while (bytesToRead > 0)
                        {
                            // Read may return anything from 0 to 10. 
                            int actualBytesRead = responseStream.Read(resultBytes, readBytes, bytesToRead);
    
                            // The end of the file is reached. 
                            if (actualBytesRead == 0)
                                break;
    
                            readBytes += actualBytesRead;
                            bytesToRead -= actualBytesRead;
                        }
    
                        responseText = Encoding.UTF8.GetString(resultBytes);
                        //responseText = Encoding.ASCII.GetString(resultBytes);
                    }
                }
            }
        }
    
        // standard responseText: 
        //<?xml version="1.0" encoding="utf-8"?>
        //<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        //    <soap:Body>
        //        <SayHelloResponse xmlns="http://tempuri.org/">
        //            <SayHelloResult>Hello</SayHelloResult>
        //        </SayHellorResponse>
        //    </soap:Body>
        //</soap:Envelope>
        if (!string.IsNullOrEmpty(responseText))
        {
            string responseElement = methodName + "Result>";
            int pos1 = responseText.IndexOf(responseElement);
    
            if (pos1 >= 0)
            {
                pos1 += responseElement.Length;
                int pos2 = responseText.IndexOf("</", pos1);
    
                if (pos2 > pos1)
                    responseText = responseText.Substring(pos1, pos2 - pos1);
            }
            else
            {
                responseText = ""; // No result
            }
        }
    
        return responseHttpStatusCode;
    }
    

    然后,您可以使用以下代码简单地调用任何web服务方法:

    var parameters = new Dictionary<string, string>();
    parameters.Add("name", "My Name Here");
    
    string responseText;
    var responseStatusCode = CallWebService("http://localhost/TestWebService.asmx", 
                                            "http://tempuri.org/", 
                                            "SayHello", 
                                            parameters, 
                                            out responseText);
    
        4
  •  3
  •   Glen    16 年前

    如果幸运的话,您仍然可以获得wsdl。一些web服务框架允许您检索动态生成的WSDL。

    使用Axis1.x编写的Web服务允许您通过浏览URL来检索动态生成的WSDL文件。

    只要浏览到

    http://server/service.soap/?wsdl
    

    不过,我不知道这是否适用于其他框架。

        5
  •  3
  •   Keith    16 年前

    嗯,这里有一个棘手的问题,但不是不可能,但我会尽我所能解释它。

    1. 创建与您在第三方服务上处理的对象架构相匹配的可序列化类。
    2. 看看你是否可以创建一个asmx,它模仿他们的服务,能够处理请求和响应(如果他们的服务关闭,这将有助于测试你的客户端应用程序)
    3. 然后,您可以从虚拟服务创建服务代理,并在调用第三方服务时更改服务url。
    4. 如果您的客户机中出现问题,那么您可以调整虚拟服务,重新生成代理并重试。

    推荐文章