Are namespaces taken into account when contacting a soap web service? - c#

I have some existing code which uses a third party SOAP client to retrieve data from another third party web service. As we switched to a new data provider, we also switched to their new endpoint. We found out that our current requests are all failing and the error we get in return is "Policy Falsified".
I have used SOAP UI to test the new web service and I can successfully obtain data this way. That is why I compared the two soap messages and found out that the problem is likely with the URI used for the soap namespace.
Code generated soap message
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Request>
//...
</Request>
</s:Body>
</s:Envelope>
Working message with SOAP UI
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Request>
//...
</Request>
</soap:Body>
</soap:Envelope>
The only differences in these messages are the namespace prefixes and the soap namespace (the data inside the request tag are identical). I would like to know if this web service is rejecting my soap message purely by the soap namespace that it's using, or that something else might play a problem?
Obviously I am likely going to need to make my own implementation to generate the soap messages myself, but I'd still like to know if the webservice is set to only accept messages with that specific soap namespace or that it's some other kind of issue?

Related

Return Multiple Elements in a SOAP Response

I'm using:
.NET Core 3.0 (C#)
SOAPCore for serialization
SQL Server
I have a pre-built SOAP service from a legacy system that is providing a request structured with two (2) Elements (RequestHeader and SearchPolicyDetails):
<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>
<RequestHeader xmlns="http://xxx">
<RequestDate>2019-11-18+05:30</RequestDate>
<SourceSystemRequestNo>1001</SourceSystemRequestNo>
</RequestHeader>
<SearchPolicyDetails xmlns="http://xxx">
<policyNumber>xxxxxxxx</policyNumber>
<asOfDate>2019-12-24</asOfDate>
</SearchPolicyDetails>
</soap:Body>
</soap:Envelope>
I can get both to run if I use a singular endpoint on my SOAP Endpoints (I.e. RequestHeader returns the data I want or SearchPolicyDetails returns the data I want. However I would like to get them to run consecutively so i can return the data from each into a single response:
<s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<RequestHeaderResponse>
{{DATA}}
</RequestHeaderResponse>
<SearchPolicyDetailsResponse>
{{DATA}}
</SearchPolicyDetailsResponse>
</s:Body>
</s:Envelope>
Is this possible since I do not know if it would be possible to get the team who built the legacy system to update the request objects. Currently if I run them in the same request the payload only returns the first Element's data.

WCF client exception: Unrecognized message version

I hit this error today when deploying a WCF client to QA:
System.ServiceModel.CommunicationException: Unrecognized message version.
In Fiddler I noticed that the WCF client sends its request wrapped in a SOAP Envelope (as expected) but that the response from the remote web service is not wrapped in a SOAP Envelope. That is, our local debug web service sends a response like this:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Response xmlns="urn:example">
<Success>true</Success>
...
</Response>
</s:Body>
</s:Envelope>
But the remote web service is just sending this:
<?xml version="1.0" encoding="utf-8"?>
<ns0:Response xmlns:ns0="urn:example">
<ns0:Success>true</ns0:Success>
...
</ns0:Response>
As far as I can tell the WCF client is throwing the exception because there's no SOAP Envelope. So my questions are:
Is my assumption correct or should be I looking elsewhere?
Is there some way to configure the WCF client's bindings to remove the SOAP Envelope expectation?
Should I just tell the remote service implementor to fix their service (which they wrote just for us from a supplied WSDL)?
The WCF client is using basicHttpBindings (and HTTP Basic Authentication over SSL/TLS). I'd considered using IClientMessageInspector.AfterReceiveReply() to rewrite the response but the exception gets thrown before that method is invoked, i.e.: We already have an implementation of it for request/response logging and it's not hitting a breakpoint in there.
More info:
After communicating with the service developer it sounds like they completely ignored the .wsdl and (svcutil generated) IService.cs files we gave them and wrote a POX (Plain-Old XML) service from scratch.
I'm not confident that we can convince them to do it properly, so now I'm looking for tips to convert a properly behaving WCF SOAP client into a POX client.
This may be caused by that your service uses Soap1.2 while you are using a different version to call it.
Please try "Add Service Reference" - "Advanced..." - "Add Web Reference..." as a compatibility approach.
I had this issue as well. I know this is an older post, but in my case I modified the app.config file in my C# .NET app that calls this web service. I think it was adding
<security mode="Transport" />
to the basicHttpBinding element that solved it. I also extended the timeouts and maxBufferPoolSize.
Microsoft has documentation that describes this, in case this helps someone else.

sending SOAP request in asp.net mvc3

I want to send following SOAP/XML request and get the SOAP response back in asp.net mvc/C#
<?xml
<soapenv:Envelope
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:myurn">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:fLocHistory 
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <HistRequest 
xsi:type="urn:SubMemLocationHistoryRequest">
            <MSID xsi:type="xsd:string">test</MSID>
            <AID xsi:type="xsd:int">2</AID>
            <MemMSISDN xsi:type="xsd:string">test</MemMSISDN>
         </HistRequest>
      </urn:fLocHistory>
   </soapenv:Body>
</soapenv:Envelope>
What is the better way to send request. I have seen example regarding MSXML2, WCF or asmx. If you could point some good starting tutorial. I have seen some examples here and here and here.

Soap web service and android client using ksoap protocal mismatch

I have and android client, that uses ksoap to communicate with a wsdl web service written in c# asp.net. I have a problem with matching the argument types between the web service and the client.
The web server expects to this kind of request (auto generated):
<?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>
<GetDetails xmlns="http://host.org/">
<event_id>int</event_id>
</GetDetails>
</soap:Body>
</soap:Envelope>
the client sends requests using ksoap, and they look like this:
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<n0:GetDetails id="o0" c:root="1" xmlns:n0="http://tempuri.org">
<event_id i:type="d:int">1</event_id>
</n0:GetDetails>
</v:Body>
</v:Envelope>
For some reason the WS parses the following' client's request as 0 (I guess because of the additional type attributes - i:type="d:int") when the request is assembled manually to look like the first option, it works correctly.
How can i make the web service read the ksoap format correctly or how can i change it's expected format to look like ksoap request. (the web service soap protocol is auto generated).
Well the solution has 2 parts:
1. regarding removing the attribute types, I found the answer here:
using addMapping without the "i:type=" attribute in ksoap2 for android
I neede to set:
envelope.implicitTypes = true;
The name space has to end with a backspace, and i missed it.

Masking sensitive information when logging from IClientMessageInspector

I'm using WCF (.NET 3.5) to communicate with a server using SOAP. When running in debug mode, I use System.ServiceMode.Dispatcher.IClientMessageInspector and log4Net to log the request content.
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
log.Debug(request);
}
My difficulty is that sometimes the SOAP message contains authentication information that I must mask before writing to the logs
e.g. in the following example I would like to log the password element as <password>**********</password>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://service.soap.host.com/credentials</Action>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<credentials xmlns="http://service..soap.host.com/credentials">
<username>MyUsername</username>
<password>MyPassword</password>
</credentials>
</s:Body>
</s:Envelope>
I'm able to achieve this in a crude way using regular expression matching on the output of request.ToString() but I wonder if there's a more elegant and efficient approach that will allow me to modify the value of the password element before converting the message to a string.
No simple way for this, except if you make sure you NEVER send credentials that way (there are many ways to send tokens instead of the actual credential).
If you're passing these information only to log on to your service, you should use SSL anyway. If that's the case, your MessageInspector could check if the current binding uses SSL or transport security and if that's the case, does not log anything.
As an aside, if you want to log messages in development, you'd be better off leveraging the WCF tracing infrastructure instead of doing the low level tracing yourself (that way you don't have to add inspectors in debug mode). See http://msdn.microsoft.com/en-us/library/ms732023.aspx for more info about built-in WCF activity and message tracing.

Categories

Resources