2009-08-14 91 views
21

我必须连接到不提供wsdl或asmx的第三方Web服务。该服务的网址只是http://server/service.soap如何调用.net中没有wsdl的Web服务

我已阅读this article关于原始服务调用,但我不确定这是我正在寻找的。

此外,我已经要求提供wsdl文件,但被告知没有(并且不会)。我使用C#与.net 2.0,并且不能升级到3.5(所以没有WCF)。我认为第三方正在使用java,因为这是他们提供的例子。

在此先感谢!

UPDATE浏览的网址时,获取这样的响应:

<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> 
+0

你应该张贴一个或更多的Java示例文件,然后将链接发布到这里。一种可能性是http://snipt.org/。 – 2009-08-14 21:33:52

+0

我已经设法连接web服务,只要我有一段时间我会发布如何做到这一点。感谢您的关注! – 2009-08-18 12:27:10

回答

20

嗯,我终于得到了这个工作,所以我会在这里写我使用的代码。 (请记住,.Net 2.0,并没有从Web服务获得wsdl)。

首先,我们创建一个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; 
} 

接下来,我们对web服务的调用,以及所需要的所有值传递。当我从XML文档读取soap信封时,我将以StringDictionary的形式处理数据。应该是一个更好的方式来做到这一点,但我会稍后考虑:

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必须添加到答案中,我会写下来。

+1

恕我直言,***我认为GetSoapXml必须添加到答案,请你写下来*** – Kiquenet 2017-10-31 11:16:08

+0

正如你可以看到这是一个8岁的问题,所以现在编写GetSoapXml有点复杂我不再在同一家公司工作,所以我无法访问代码。 – 2017-11-02 08:30:25

2

如果你很幸运,你仍然可以得到的WSDL。一些Web服务框架允许您检索动态生成的WSDL。

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

只需浏览到

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

我不知道这是否可能与其他框架虽然。

+0

试过这个,没有工作。感谢无论如何:) – 2009-08-14 10:56:54

+0

认为这是一个远射。你知道该框架(如果有的话)服务是写入吗?如果没有WSDL,那么你应该如何使用这个服务?他们有任何指导方针吗? – Glen 2009-08-14 11:04:41

+0

他们已经提供了一些.java文件作为示例,但因为我对Java没有任何了解...... – 2009-08-14 14:53:22

3

嗯,棘手的一个在这里,但不是不可能的,但我会尽我所能来阐述它。

什么你需要做的是

  1. 创建与您正在处理的第三方服务对象架构可序列化类。
  2. 看看他们是否使用任何的SOAPAction在他们的服务电话
  3. 看看你能不能创造出模仿他们的服务在能够处理请求和响应方面的ASMX(这将是很好的,如果测试您的客户端应用程序的服务已关闭)
  4. 然后,您可以从虚拟服务创建服务代理,并在调用第三方服务时更改服务网址。
  5. 如果某些东西在您的客户端不起作用,那么您可以调整您的虚拟服务,重新生成代理并重试。

我会尝试添加更多的,当我想到它,但这应该足以让你开始。

+0

我会寻找这方面的信息,但请发布您认为有用的任何信息。 – 2009-08-14 11:09:33

+0

是的,希望他们甚至有这个XML模式。 OTOH,如果您打算对虚拟服务进行任何操作,请勿对ASMX执行任何操作 - 请改用WCF。 – 2009-08-14 16:07:44

+0

WCF是否与2.0兼容?我认为它只能用于3.0 – 2009-08-14 17:54:16

10

在我看来,SOAP Web服务没有理由不提供WSDL。它不需要由服务动态生成;它不需要通过互联网。但有必须是一个WSDL,即使他们必须发送给您软盘拇指驱动器!

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

+0

记录了用于发送和检索信息的XML方案。我唯一缺乏的是正确连接它的知识。 对于提供它的公司,是一家保险公司,所以没有抱怨的可能性:( – 2009-08-14 17:52:44

+1

其实,我强烈反对这一观点。这些模式是任何行业标准的一部分,是来自行业标准组织(国际还是非国际) 。如果是这样,这给了你一个要点,而且这个行业里有很多其他的开发人员可以和你一起推动,而不是像你要求他们做一些非常复杂或昂贵的事情,特别是如果他们已经有了一种分配模式的机制,即使它是公司特有的,一旦他们得到了模式,其余的都很容易。 – 2009-08-14 18:05:29

+0

任何运气发现他们为什么不想提供WSDL?也许你应该得到一个试用XMLspy,并向他们展示它是多么容易,因为他们已经获得了XML模式。 – 2009-08-19 06:58:17

1

我已经创建了下面的辅助方法调用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); 
+0

我会试试这个 - 如果它有效,那么为什么你只有一个upvote会是一个谜。 – 2017-08-08 09:17:30

+0

我唯一需要的扩展就是包含一个SoapHeader .. – 2017-08-08 09:26:47