2009-08-14 76 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