I have a web service that makes SOAP requests to our clients server (I do not have access to that server and have no idea how the web service methods are implemented).
The code on our part has not changed recently and has worked ok previously (and still works for most part), but the client has been reporting that a lot of our requests have been failing daily for at least a month due to "duplicate XML declaration" logged inside Data Power.
The SOAP message they receive is truncated (lots of data missing) and at the end of the XML, the initial SOAP headers are duplicated. It looks like they receive the message partially, then some error occurs, then try reprocessing it and that fails again. Basically it looks something like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sendData>
<requestHeader>
//PARTIAL INFORMATION INCLUDED HERE
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sendProspect xmlns="http://webservices.zurich.com/zsoa/fig/policyacquisition/prospectquote-v1_0">
<requestHeader>
What could cause the the SOAP message to get truncated? I am thinking about some sort of communication error between client and server, or maybe web server changes, but I was wondering if someone else has had this problems and could offer some suggestions.
EDIT: added the HTTP header received from the client:
POST <webservice> HTTP/1.1
http_racfid: <info>
SOAPAction: ""
MULE_ENCODING: UTF-8
Host: <hostInfo>
Connection: keep-alive
Accept: */*
Content-Type: text/xml
Content-Length: 41341
duplicate XML declaration in DataPower typically happens when you have a stylesheet Action in your Processing Policy that doesn't detect valid XML and it tries to "fix" it.
This would indicate that you don't get the full XML from the server.
Enable the Probe for the service and have a look at the INPUT xml.
You can also in default domain start a Packet Capture as suggested in the comments or start a File Capture to get any messages coming in. NB! Both Packet Capture and File Capture are giving a severe performance hit so you shouldn't do it in a high volume production environment!
Another, less intrusive, way of getting the "real" INPUT is to add a GatewayScript Action directly after the Match action which writes the INPUT to a temporary:/// file which you can review. This is "safer" as the temporary:/// storage cleans it self up...
Related
I've followed Microsoft's Get started with EWS Managed API client applications tutorial, in an effort to build an application that will get specific items from a mailbox on an Exchange server.
It seems that after the initial auto-discover operations succeed, no matter what kind of request I send through the API, I get a response back containing the following:
HTTP/1.1 415 Cannot process the message because the content type 'text/plain; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'.
With Microsoft.Exchange.WebServices.Data.ExchangeService.TraceEnabled = true, the trace of a typical request looks like this (this one is generated by calling Folder.Bind(service, "IT", propSet)):
<?xml version="1.0" encoding="utf-16"?>
<Trace Tag="EwsRequest" Tid="1" Time="2019-03-01 14:42:02Z" Version="15.0.913.15">
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013" />
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
</m:FolderShape>
<m:FolderIds>
<t:FolderId Id="IT" />
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
</Trace>
It looks like the Content-Type header is missing altogether, so the server sees the request as text/plain; charset=utf-8. It shouldn't be a problem to add Content-Type: text/xml; charset=utf-8 to requests that the ExchangeService object makes, but the member Dictionary HttpHeaders is not settable (see the interface in ExchangeServiceBase).
Any idea how I can either send the server an acceptable request with the EWS Managed API, or configure the target Exchange server so that it accepts the requests I'm sending? I've come across lots of related SO questions, but none with an actual answer to this problem.
I was getting the same error and the only clue I could find was this thread.
I eventually fixed it by switching to Microsoft.Exchange.WebServices.NETStandard -v 1.1.3 (from -v 2.0.0-beta1).
Our partner says he is going to send data using the SOAP protocol without using any service name to post data, like HelloWorld(string p1), just a POST.
So I am wondering how is it possible to do with SOAP?
I mean in WCF / web services, we need the name of method anyway, right?
Any clues? Thank you!
UPDATE #1
Using Wireshark I am getting this message
POST HTTP/1.1
Content-Type: text/xml
User-Agent: SOAP Sender v1.2
Host: 191.126.125.5:1212
Authorization: Basic QFNLVXNlcjE4MTghOiBAU0tQYTE5MTkh
Content-Length: 708
<?xml version="1.0" encoding="windows-1251"?>
<soapenv:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope">
<soapenv:Header/>
<soapenv:Body>
<ws:PutCoord>
<ObjectID>SG255108374</ObjectID>
</ws:PutCoord>
</soapenv:Body>
</soapenv:Envelope>
So what sort of .NET application I have to create to get this POSTED data?
This correspond to https://www.w3.org/TR/soap12-part0/#L26866
I was misled by my client HelpDesk. :)
They send data in SOAP format using HTTP to some port and thats it.
So... Sometimes HelpDesk is gonna confuse you. Hahahaha! Be careful!
I am implementing a .net OData client with WCF. This uses OData version 3. The service is implemented by a vendor. When saving an object with a missing property, the server returns an error. But the error response does not have the right format (Specification). Therefore, the DataServiceContext.SaveChanges(...) method always throws:
System.Net WebException: "The remote server returned an error: (400) Bad Request."
With this exception I don't have any possibility to get the reason of the error--no InnerException is set.
How does such an error response look like, so that the WCF DataServiceContext.SaveChanges(...) detects an error and I can get the information I need?
Thanks in advance.
EDIT:
I used fiddler to change the response from the server. With this I tried to find the right formatted response. This is the last version I tried after rereading the specification and considering the comments:
HTTP/1.1 40 Bad Request
Cache-Control: private
Content-Type: application/atom+xml;type=feed
Date: Wed, 11 May 2016 08:02:07 GMT
Content-Length: 243
DataServiceVersion: 3.0;
<?xml version="1.0" encoding="utf-8"?>
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<m:code />
<m:message xml:lang="en-US">
Resource not found for the segment 'Productss'.
</m:message>
</m:error>
Sadly it's still not working.
The error you are getting is not because the client cannot read the response, it's an Exception that's telling you that the server didn't "like" the request you sent to it.
400 Bad Request is usually used to notify a client that the request it sent to server was malformed.
The error should go away once you send the request to server in the correct structure.
Hope it helps!
I am currently trying to consume a generated report as a webservice to integrate some data into our system. Because the service itself is generated, the response can change frequently as things are added to it. While the endpoint and response may change, the request body will always be the same (taken from soapui):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<Execute_Report>
</Execute_Report>
</soapenv:Body>
</soapenv:Envelope>
I'm trying to figure out a way to make the above request for any endpoint (different reports) and allow for changes in the response. Ideally, I want to just return the raw XML of the response as I can allow for change easier with how I handle the XML if I'm not being tied to a data contract.
It is also worth noting that the service uses WS-Security and a Username/Password is passed as part of the request.
I've used WCF and the files generated from svcutil work great when I don't expect the service to change frequently. However because these webservices are generated change is expected, and if I can get away from it, I don't want to be at the mercy of re-generating a new file with svcutil whenever things change, or have to generate a file (and maintain) for all the different generated webservices.
At the end of the day the question is: How do I consume a webservice and return the raw XML while still being able to apply WS-Security to the request?
I kept searching around and found this answer:
.NET client authentication and SOAP credential headers for a CXF web service
This allowed me to do what I was after.
I'm trying to develop an app that works with an existing soap client. I don't think it uses any WSDL/etc. It just uses soap as a form of communication.
Example of what the client sends:
POST /SNSR_STD-SOAP HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "someCommand"
Host: 192.168.0.17:12345
Content-Length: 487
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- There is something in here obviously... -->
</s:Body>
</s:Envelope>
Now I want to be able to write a server that fetches those messages, gets the SOAPAction in the HTTP header and also the soap envelope/xml conviniently so I could reach all fields.
I started reading about WCF and services, and also followed MSDN getting started to WCF and server/client software, but it demonstrates creating a calculator service that works with wsdl etc, which is not the case here.
So the question - what is the preferred way of doing this? WCF? Services? How exactly do I launch the server, via IIS, maybe something else which is more automatic?
In the same manner, I need to write a soap client that sends such messages back to the client (which is now also a server). How do I do that?
I need the simplest most elegant way for doing this.
Thanks a lot.
You can do that, but you will have to work directly with the Message class (look at Message Headers too) and use Message Inspectors to "intercept" the message at a lower level.