Benutzer mit den meisten Antworten
WebService-Programmierung mit HTTP-Post und XML

Frage
-
Hallo an die Experten,
ich muss Daten bei einem WebService abfragen. Das habe ich mit diesem Code-Schnipsel gelöst (xd enthält ein XmlDocument).
WebRequest req = WebRequest.Create("http://Internet.html"); byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(xd.InnerXml); req.Method = "POST"; req.ContentType = "text/xml"; req.ContentLength = requestBytes.Length; Stream requestStream = req.GetRequestStream(); requestStream.Write(requestBytes, 0, requestBytes.Length); requestStream.Close(); WebResponse res = req.GetResponse(); StreamReader sr = new StreamReader(res.GetResponseStream(), System.Text.Encoding.Default); MessageBox.Show(sr.ReadToEnd(), "Erfolg"); sr.Close(); res.Close();
Funktioniert soweit.
Nun muss ich das Gegenstück programmieren, also einen WebService.
Probiert habe ich es so:
[WebMethod(Description = "Test WebService")] public getBookingAvailabilityResponse GetAvailability(XmlDocument xd) { // Xml-Daten verarbeiten und zurückgeben getBookingAvailability GetBookingAvailability = new getBookingAvailability(xd); getBookingAvailabilityResponse resp = new getBookingAvailabilityResponse(); return resp; }
Problem ist nur: Der Client bekommt immer Fehler 500 und meldet "GetAvailability ist kein gültiger WebDienst-Methodenname.
Ich bekomme einfach den Parameter nicht korrekt übergeben.
Kann jemand helfen?
Mfg
Micha
Antworten
-
Hallo Micha,
im Endeffekt ist das nicht anderes als ein String, der zufälligerweise XML enthält. Damit das über einen Webservice (der das ganze auch in einer XML Struktur empfängt) funktioniert, sollte der XML Teil, den Du senden willst, codiert werden. Ich persönlich wähle hier meist Base64, dann muss ich mich nicht um die ganzen XML Eigenheiten kümmern.
Im Endeffekt müsstest Du also deinem Client lediglich sagen, dass er vor dem dem Aufruf der Webservicemethode den Inhalt deines XMLDocument als String lesen und per Base64 codieren soll. Auf der Serverseite nimmst Du den String und decodierst ihn wieder.
Falls es evtl. Verständnisprobleme gibt, hab ich mal ein "Oldstyle" Beispiel in VBScript, daran siehst Du, wie man einen Webservice auch komplett manuell aufrufen kann und wie der Aufruf aufgebaut werden muss. Für deine Anforderungen musst Du das natürlich ein wenig anders machen, das Beispiel sollte aber zeigen, wie es gehen kann.
<% Const Address = "http://dein.server.tld/Webservices/DeinWebservice.asmx" Dim Parameters Parameters = "<?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://schemas.xmlsoap.org/soap/envelope/"">" & _ " <soap:Body>" & _ " <AddComplexType xmlns=""http://tempuri.org/"">" & _ " <NewItem>" & _ " <ID>4711</ID>" & _ " <Name>Neuer Eintrag</Name>" & _ " <Email>neue@emailadresse.tld</Email>" & _ " </NewItem>" & _ " </AddComplexType>" & _ " </soap:Body>" & _ "</soap:Envelope>" Dim objHTTP Set objHTTP = Server.CreateObject("WinHttp.WinHttpRequest.5.1") objHTTP.SetTimeouts 5000, 5000, 5000, 5000 objHTTP.open "POST", Address, false objHTTP.setRequestHeader "Content-Type", "text/xml; charset=utf-8" objHTTP.setRequestHeader "Content-Length", "application/x-www-form-urlencoded" objHTTP.send Parameters strResult = objHTTP.ResponseText If strResult <> "" Then Response.ContentType = "text/xml" Response.Write strResult Else Response.Write "No response from webservice" End if Set objHTTP = Nothing %>
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert MichaMoll Dienstag, 4. September 2012 15:14
Alle Antworten
-
Hi,
in solchen Fällen ist es sinnvoll, sich mal mit irgendeinem Tool (Firebug, Fiddler, ...) anzuschauen, was normalerweise durch die Leitung geschickt wird.
Die Webservices haben bei lokalem Aufruf und nicht komplexen Übergabetypen auch Testmethoden. Daran kann man sehen, dass der Aufbau einem Schema entspricht. Alternativ einfach mal an der Visual Studio Eingabeaufforderung wcftestclient eingeben, den Dienst dort abonnieren und dann schauen, was übergeben wird.
Ich frage mich allerdings, warum Du den ganzen Kram überhaupt manuell machen willst? Füg in deinem Projekt doch einfach einen Webverweis auf den Webservice hinzu und lass Visual Studio den Rest machen. VS generiert Proxyklassen, alle Methoden zum Aufrufen der Methoden inkl. Rückgabe, usw.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Stefan,
das ist ja mein Problem: Die Übergabetypen sind XML-Dateien und somit "komplex". Da hilft mir keine Testmethode und auch wcftestclient muss leider passen.
Ich muss das insofern manuell machen, da ich ja den Web-Service erstellen muss. Die Vorgabe dabei lautet: Die Daten werden über http-POST (und nicht SOAP) übergeben. Das scheint (?) durch VS nicht automatisch unterstützt zu werden...
Ich hatte gestern Nacht noch ein andere Idee: Möglicherweise ist ein Web-Service in diesem Fall der völlig falsche Ansatz. Wenn die Daten per http-POST übergeben werden sollen, so müsste es eigentlich auch ein httpListener tun. Ich werde das mal in diese Richtung weiter verfolgen...
Gruß
Micha
- Bearbeitet MichaMoll Montag, 3. September 2012 17:45
-
Hallo Micha,
im Endeffekt ist das nicht anderes als ein String, der zufälligerweise XML enthält. Damit das über einen Webservice (der das ganze auch in einer XML Struktur empfängt) funktioniert, sollte der XML Teil, den Du senden willst, codiert werden. Ich persönlich wähle hier meist Base64, dann muss ich mich nicht um die ganzen XML Eigenheiten kümmern.
Im Endeffekt müsstest Du also deinem Client lediglich sagen, dass er vor dem dem Aufruf der Webservicemethode den Inhalt deines XMLDocument als String lesen und per Base64 codieren soll. Auf der Serverseite nimmst Du den String und decodierst ihn wieder.
Falls es evtl. Verständnisprobleme gibt, hab ich mal ein "Oldstyle" Beispiel in VBScript, daran siehst Du, wie man einen Webservice auch komplett manuell aufrufen kann und wie der Aufruf aufgebaut werden muss. Für deine Anforderungen musst Du das natürlich ein wenig anders machen, das Beispiel sollte aber zeigen, wie es gehen kann.
<% Const Address = "http://dein.server.tld/Webservices/DeinWebservice.asmx" Dim Parameters Parameters = "<?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://schemas.xmlsoap.org/soap/envelope/"">" & _ " <soap:Body>" & _ " <AddComplexType xmlns=""http://tempuri.org/"">" & _ " <NewItem>" & _ " <ID>4711</ID>" & _ " <Name>Neuer Eintrag</Name>" & _ " <Email>neue@emailadresse.tld</Email>" & _ " </NewItem>" & _ " </AddComplexType>" & _ " </soap:Body>" & _ "</soap:Envelope>" Dim objHTTP Set objHTTP = Server.CreateObject("WinHttp.WinHttpRequest.5.1") objHTTP.SetTimeouts 5000, 5000, 5000, 5000 objHTTP.open "POST", Address, false objHTTP.setRequestHeader "Content-Type", "text/xml; charset=utf-8" objHTTP.setRequestHeader "Content-Length", "application/x-www-form-urlencoded" objHTTP.send Parameters strResult = objHTTP.ResponseText If strResult <> "" Then Response.ContentType = "text/xml" Response.Write strResult Else Response.Write "No response from webservice" End if Set objHTTP = Nothing %>
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert MichaMoll Dienstag, 4. September 2012 15:14
-
Hallo MichaMoll,
Noch für Dich zum lesen: Making Asynchronous Requests - asynchronous calls with the WebRequest class.
Grüße,
Robert
Robert Breitenhofer, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.