2009-08-14 11 views
21

Muszę połączyć się z usługą sieciową innej firmy, która nie obsługuje wsdl ani asmx. Adres URL usługi to tylko http://server/service.soapJak nawiązać połączenie z serwisem WWW bez klucza wsdl w sieci .net

Przeczytałem this article o wywołaniach usług nieprzetworzonych, ale nie jestem pewien, czy tego właśnie szukam.

Ponadto, prosiłem o pliki wsdl, ale powiedziano mi, że nie ma żadnych (i nie będzie).

Używam C# z .net 2.0, i nie można uaktualnić do wersji 3.5 (więc nie ma jeszcze WCF). Sądzę, że strona trzecia używa java, ponieważ jest to przykład, który dostarczyli.

Z góry dziękuję!

UPDATE Pobierz tę odpowiedź podczas przeglądania link:

<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

Należy zakładać jedną lub więcej przykładowych plików Java gdzieś, a następnie opublikować link do nich tutaj. Jedną z możliwości jest http://snipt.org/. –

+0

Udało mi się połączyć serwis internetowy, gdy tylko będę miał trochę czasu, opublikuję, jak to zrobić. Dzięki za zainteresowanie! –

Odpowiedz

20

Cóż, w końcu udało mi się to zrobić, więc napiszę tutaj kod, którego używam. (Pamiętaj, .Net 2.0, i nie ma wsdl, aby uzyskać z usługi internetowej).

Najpierw tworzymy 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; 
} 

Następnie wykonujemy połączenie z usługa, przechodząc wzdłuż wszystkich potrzebnych wartości. Ponieważ czytam kopertę mydła z dokumentu xml, traktuję dane jako StringDictionary. Powinien to być lepszy sposób, ale pomyślę o tym później:

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; 
} 

To wszystko. Jeśli ktokolwiek myśli, że GetSoapXml musi zostać dodany do odpowiedzi, zapiszę to.

+1

IMHO, *** Myślę, że GetSoapXml musi zostać dodany do odpowiedzi, proszę, zapiszesz go *** – Kiquenet

+0

Jak widzisz, jest to 8-letnie pytanie, więc napisanie GetSoapXml teraz jest nieco skomplikowane Nie pracuję już w tej samej firmie, więc nie mam dostępu do kodu. –

2

Jeśli masz szczęście można jeszcze dostać WSDL. Niektóre środowiska usług sieciowych umożliwiają pobieranie dynamicznie generowanego pliku WSDL.

Usługi internetowe napisane w Axis1.x umożliwiają pobieranie dynamicznie generowanego pliku WSDL przez przeglądanie pod adresem URL.

Wystarczy przejść do

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

Nie wiem, czy jest to możliwe z innych ram chociaż.

+0

Próbowałem tego, nie działało. Dzięki i tak :) –

+0

myślałem, że to było trochę długie ujęcie. Czy wiesz, że ta frameworka (jeśli taka istnieje) jest napisana? Jeśli nie ma WSDL, to w jaki sposób ma się korzystać z tej usługi? Czy mają dla ciebie jakieś wytyczne? – Glen

+0

Przesłano niektóre pliki .java jako przykład, ale jak ja nic nie wiem o Javie ... –

3

Hmm, podstępny tutaj, ale nie niemożliwy, ale zrobię co w mojej mocy, aby go wyrzucić.

Co trzeba zrobić, to

  1. Tworzenie serializacji klas, które pasują do schematów obiektów masz do czynienia z na usługi osób trzecich.
  2. Dowiedz się, czy używają SOAPAction w swoich rozmowach serwisowych
  3. Sprawdź, czy możesz utworzyć asmx, który naśladuje ich usługę pod kątem obsługi żądań i odpowiedzi (to będzie dobre dla testowania aplikacji klienckiej, jeśli ich usługa jest wyłączona).
  4. Następnie można utworzyć serwer proxy usługi z fikcyjnej usługi i zmienić adres URL usługi podczas wywoływania usługi innej firmy.
  5. Jeśli coś nie działa w twoim kliencie, możesz dostosować swoją sztuczną usługę, ponownie wygenerować proxy i spróbować ponownie.

Postaram się dodać więcej, kiedy o tym myślę, ale to powinno wystarczyć.

+0

Poszukuję informacji na ten temat, ale proszę, opublikuj wszelkie informacje, które uważasz za użyteczne. –

+0

Tak, mam nadzieję, że mają nawet schemat XML. OTOH, jeśli masz zamiar zrobić cokolwiek z fałszywą usługą, nie rób nic z ASMX - użyj zamiast tego WCF. –

+0

Czy jest zgodny z WCF z wersją 2.0? Myślę, że można go używać tylko z 3.0 –

10

Moim zdaniem, nie ma usprawiedliwienia dla usługi sieciowej SOAP, aby nie dostarczać WSDL. Nie musi być dynamicznie generowane przez usługę; nie musi być dostępny przez Internet. Ale musi być musi być WSDL, nawet jeśli muszą wysłać go do ciebie na dysku kciuka!

Jeśli masz możliwość złożenia skargi do dostawców usług, to zachęcam Cię do tego. Jeśli masz możliwość odepchnięcia, zrób to. Najlepiej byłoby zmienić dostawców usług i powiedzieć tym osobom, że nie podali WSDL.Przynajmniej dowiedz się, dlaczego nie uważają tego za ważne.

+0

Schemat XML do wysyłania i pobierania informacji jest udokumentowany. Jedyne, czego mi brakuje, to wiedza, jak prawidłowo się z nim połączyć. Jeśli chodzi o firmę świadczącą tę usługę, jest to firma ubezpieczeniowa, więc nie ma możliwości składania reklamacji :( –

+1

W rzeczywistości zdecydowanie się z tym nie zgadzam. Czy są to schematy należące do dowolnego standardu branżowego, od organizacji branżowej (międzynarodowej lub nie)? Jeśli tak, to daje ci jeden punkt, na który możesz naciskać, a także przemysł pełen innych programistów, którzy mogliby dołączyć do ciebie w popychaniu.To nie jest tak, że prosisz ich o zrobienie czegoś bardzo skomplikowanego lub kosztownego, szczególnie jeśli już mają mechanizm do dystrybucji schematów, nawet jeśli jest to specyficzne dla firmy, gdy już mają schematy, reszta jest dość łatwa –

+0

Dowiedzieć się, dlaczego nie chcą dostarczyć WSDL? wypróbować XMLspy i pokazać im, jak łatwo by to było, skoro mają już schematy XML –

1

Stworzyłem następującej metody pomocnika zadzwonić WebService ręcznie bez jakiegokolwiek odniesienia:

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; 
} 

Następnie można po prostu wywołać dowolną metodę usługi internetowej z następującego kodu:

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

Mam zamiar tego spróbować - jeśli to zadziała, to będzie tajemnicą, dlaczego masz tylko jeden z nich. –

+0

Moje jedyne konieczne rozszerzenie do powyższego byłoby włączenie SoapHeader .. –

Powiązane problemy