I am encountering issue sending a SOAP request containing special char to a Web Service. I have a WinForm textbox where user input text such as "1€" for instance. Then I call a WS method which aims to store the data into database.
I implemented the IClientMessageInspector in order to intercept the
SOAP inbound/outbound messages, and noticed that the string sent to server is "1▒" :
<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">urn:MYWebService#insertData</Action>
</s:Header>
<s:Body s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<q1:insertData xmlns:q1="urn:MYWebService">
<note xsi:type="xsd:string">1▒</note>
</q1:insertData>
</s:Body>
</s:Envelope>
Therefore data stored in database table is "1?".
I did many tries, such as using WebUtility.HtmlEncode without success. I am wondering whether I have to do an action on client side or server one. Can you please advise me about any suggestion to follow?
What was the HtmlEncode returning for you? I would suspect something like
<note xsi:type="xsd:string">1€</note>
should have some effect.
Related
Question:
Why would I receive a SOAP response fragment that contains a duplicate tag prefix namespace?
Why would I receive a different response fragment in SoapUI versus a WCF client using the exact same SOAP request?
Context:
I am calling a third-party, Java based web service with a WCF client. The SOAP fragment response sent from the third party WS contains a duplicate namespace and tag prefix for the soap envelope on the Fault tag line when calling with an incorrect value that results in a fault response. This causes the WCF to throw a CommunicationException with an innerException of XmlException which cites the following as the error:
Start element 'faultcode' from namespace '' expected. Found element 'SOAP-ENV:faultcode'
from namespace 'http://schemas.xmlsoap.org/soap/envelope/'.
This error message leads me to believe the duplicated namespace in the SOAP fragment is the culprit. The weird thing is, using the exact SOAP request sent from the WCF client to the web service in SoapUI does not result in this namespace being duplicated in the SOAP response fragment.
The WCF client is using a basicHttpBinding.
Please see below for SOAP fragments of the request, response through WCF, and response through SoapUI.
Request sent by both WCF and SoapUI:
<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">
<Search xmlns="urn:ent.soap.testservice.com/objs">
<Request objType="Report">
<RequestorId>ABCD</RequestorId>
<TargetId></TargetId>
</Request>
</Search>
</s:Body>
</s:Envelope>
Response received by WCF client:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:faultcode>SOAP-ENV:Server</SOAP-ENV:faultcode>
<SOAP-ENV:faultstring>Invalid action parameters</SOAP-ENV:faultstring>
<SOAP-ENV:detail>
<fns:fault xmlns:fns="urn:fault.soap.testservice.com" xmlns:java="java" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="fns:ApiFault">
<fns:exceptionCode>INTERNAL_ERROR</fns:exceptionCode>
<fns:exceptionMessage>Invalid action parameters</fns:exceptionMessage>
<fns:logDataExchangeId>1234567890</fns:logDataExchangeId>
</fns:fault>
</SOAP-ENV:detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Response received by SoapUI:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<SOAP-ENV:faultcode>SOAP-ENV:Server</SOAP-ENV:faultcode>
<SOAP-ENV:faultstring>Invalid action parameters</SOAP-ENV:faultstring>
<SOAP-ENV:detail>
<fns:fault xsi:type="fns:ApiFault" xmlns:fns="urn:fault.soap.testservice.com" xmlns:java="java" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<fns:exceptionCode>INTERNAL_ERROR</fns:exceptionCode>
<fns:exceptionMessage>Invalid action parameters</fns:exceptionMessage>
<fns:logDataExchangeId>1234567890</fns:logDataExchangeId>
</fns:fault>
</SOAP-ENV:detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The problem is not the duplicated namespace declaration. The problem is in this bit:
<SOAP-ENV:faultcode>SOAP-ENV:Server</SOAP-ENV:faultcode>
<SOAP-ENV:faultstring>Invalid action parameters</SOAP-ENV:faultstring>
On the SOAP Specification, the faultcode and faultstring elements are in the empty, default namespace, not in the "http://schemas.xmlsoap.org/soap/envelope/" namespace. So it really should've looked something like this:
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:MustUnderstand</faultcode>
<faultstring>SOAP Must Understand Error</faultstring>
</SOAP-ENV:Fault>
So looks like this service in particular is not being compliant with the SOAP 1.1 (or 1.2 for that matter) specification.
While trying to invoking my Amadeus Fare_masterpricetravelboard Service using SoapUI like mozila poster, Google restclient app, or my .net code, it returns the following error message:
A header representing a Message Addressing Property is not valid and the message cannot be processed
The same webservice is working fine in SOAP UI Tool.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sec="http://xml.amadeus.com/2010/06/Security_v1" xmlns:typ="http://xml.amadeus.com/2010/06/Types_v1" xmlns:iat="http://www.iata.org/IATA/2007/00/IATA2010.1" xmlns:app="http://xml.amadeus.com/2010/06/AppMdw_CommonTypes_v3" xmlns:link="http://wsdl.amadeus.com/2010/06/ws/Link_v1" xmlns:ses="http://xml.amadeus.com/2010/06/Session_v3" xmlns:fmp="http://xml.amadeus.com/FMPTBQ_10_3_1A">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<add:MessageID xmlns:add="http://www.w3.org/2005/08/addressing">65449120-2aa0-46b0-9dcc-c40c6439836c</add:MessageID>
<wsa:Action>http://webservices.amadeus.com/FMPTBQ_10_3_1A</wsa:Action>
<add:To xmlns:add="http://www.w3.org/2005/08/addressing">https://nodeD1.test.webservices.amadeus.com/1ASIWIBEWWZ</add:To>
<link:TransactionFlowLink xmlns:link="http://wsdl.amadeus.com/2010/06/ws/Link_v1" />
<oas:Security xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<oas:UsernameToken oas1:Id="UsernameToken-1" xmlns:oas1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<oas:Username>WSWWZIBE</oas:Username>
<oas:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">EoCeDbDbThB=</oas:Nonce>
<oas:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">Hr2HRG8j0dTH19kh52wQ5aqMxhU=</oas:Password>
<oas1:Created>2014-07-19T12:33:47:530Z</oas1:Created>
</oas:UsernameToken>
</oas:Security>
<AMA_SecurityHostedUser xmlns="http://xml.amadeus.com/2010/06/Security_v1">
<UserID POS_Type="1" PseudoCityCode="THRI4213V" RequestorType="U" />
</AMA_SecurityHostedUser>
</soapenv:Header>
<soapenv:Body>
<Fare_MasterPricerTravelBoardSearch>
<numberOfUnit>
<unitNumberDetail>
<numberOfUnits>1</numberOfUnits>
<typeOfUnit>PX</typeOfUnit>
</unitNumberDetail>
<unitNumberDetail>
<numberOfUnits>250</numberOfUnits>
<typeOfUnit>RC</typeOfUnit>
</unitNumberDetail>
</numberOfUnit>
<paxReference>
<ptc>ADT</ptc>
<traveller>
<ref>1</ref>
</traveller>
</paxReference>
<fareOptions>
<pricingTickInfo>
<pricingTicketing>
<priceType>RP</priceType>
<priceType>RU</priceType>
<priceType>TAC</priceType>
</pricingTicketing>
</pricingTickInfo>
</fareOptions>
<itinerary>
<requestedSegmentRef>
<segRef>1</segRef>
</requestedSegmentRef>
<departureLocalization>
<departurePoint>
<locationId>CDG</locationId>
</departurePoint>
</departureLocalization>
<arrivalLocalization>
<arrivalPointDetails>
<locationId>LHR</locationId>
</arrivalPointDetails>
</arrivalLocalization>
<timeDetails>
<firstDateTimeDetail>
<timeQualifier>TA</timeQualifier>
<date>041114</date>
<time>2200</time>
<timeWindow>4</timeWindow>
</firstDateTimeDetail>
<rangeOfDate>
<rangeQualifier>C</rangeQualifier>
<dayInterval>1</dayInterval>
</rangeOfDate>
</timeDetails>
</itinerary>
</Fare_MasterPricerTravelBoardSearch>
</soapenv:Body>
</soapenv:Envelope>
Response:
<soap:Envelope>
<soap:Header>
<wsa:Action>http://www.w3.org/2005/08/addressing/fault</wsa:Action>
<wsa:MessageID>urn:uuid:0ce4ebc0-7753-6394-4945-c7e8f81c2c49</wsa:MessageID>
<wsa:RelatesTo RelationshipType="http://www.w3.org/2005/08/addressing/reply">65449120-2aa0-46b0-9dcc-c40c6439836c</wsa:RelatesTo>
<wsa:FaultDetail>
<wsa:ProblemHeaderQName>wsa:To</wsa:ProblemHeaderQName>
<wsa:ProblemIRI>https://nodeD1.test.webservices.amadeus.com/1ASIWIBEWWZ</wsa:ProblemIRI>
</wsa:FaultDetail>
</soap:Header>
<soap:Body>
<soap:Fault>
<faultcode>wsa:InvalidAddressingHeader</faultcode>
<faultstring>A header representing a Message Addressing Property is not valid and the message cannot be processed</faultstring>
<faultactor>SI:muxDZ1</faultactor>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Be sure that the url of the web request matches the value of the tag "add:To", including letter case.
Probably you are developing in .net and, even if you set the url in the same letter case, the request will be sent to the address in lowercase. So nodeD1 become noded1 in http layer but remains nodeD1 in soap envelope. Be careful to use lowercase or uppercase in both fields
This could be because of SOAPAction as well.
In my case ,
Soap UI internally uses : http://webservices.amadeus.com/{{orgCode}}/FMPTBQ_21_4_1A
when generating stub, orgCode is missed it came as http://webservices.amadeus.com/FMPTBQ_21_4_1A
After changing SoapAction explicitly in the code, started working.
I am calling a Java WebLogic web service from my .Net application. I have added a service reference to the jws service.
The service can be called fine and I can see the response in Fiddler, however the problem is that the propery listOfHolds is coming as null although I can see a list of holds in the XML of the response.
Here is the code for calling
holdsList result = proxy.viewHoldsList(request.AccountNo);
int noOfHolds = result.NumberOfHolds; // This value is read fine
object[] holds = result.listOfHolds; // This is coming as Null despite the values in the response
Here is the response XML as captured by Fiddler
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<work:WorkContext xmlns:work="http://oracle.com/weblogic/soap/workarea/">rO0...AAA</work:WorkContext>
</S:Header>
<S:Body>
<ns0:viewHoldsListResponse xmlns:ns0="http://www.openuri.org/">
<ns0:viewHoldsListResult>
<ns0:TotalAmount>130.0</ns0:TotalAmount>
<ns0:NumberOfHolds>4</ns0:NumberOfHolds>
<ns0:listOfHolds>
<ns0:item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns0:holdDetails">
<ns0:xsiType>HoldDetails</ns0:xsiType>
<ns0:Amount>100.0</ns0:Amount>
<ns0:StartDate>2014-02-15T00:00:00.0</ns0:StartDate>
<ns0:ExpiryDate>2014-02-20T00:00:00.0</ns0:ExpiryDate>
<ns0:Description>For testing</ns0:Description>
<ns0:Instruction/>
<ns0:Tracer>00000810000287294002</ns0:Tracer>
<ns0:HoldId>3591376655</ns0:HoldId>
<ns0:EmployeeId>0</ns0:EmployeeId>
</ns0:item>
<ns0:item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns0:holdDetails">
<ns0:xsiType>HoldDetails</ns0:xsiType>
<ns0:Amount>10.0</ns0:Amount>
<ns0:StartDate>2014-02-15T00:00:00.0</ns0:StartDate>
<ns0:ExpiryDate>2014-02-17T00:00:00.0</ns0:ExpiryDate>
<ns0:Description>DESC</ns0:Description>
<ns0:Instruction/>
<ns0:Tracer>00000810000287294004</ns0:Tracer>
<ns0:HoldId>3591376656</ns0:HoldId>
<ns0:EmployeeId>0</ns0:EmployeeId>
</ns0:item>
</ns0:listOfHolds>
</ns0:viewHoldsListResult>
</ns0:viewHoldsListResponse>
</S:Body>
</S:Envelope>
I have faced a similar problem before and the problem was a missing xmlns attribute on one of the tags. In this case I am suspecting the extra <ns0:xsiType>HoldDetails</ns0:xsiType> tag that is coming under the <ns0:item> tag.
Update Even after the web service provider removed the extra <xsiType> tag, I am unable to read the listOfHolds.
My questions are:
Can I do anything in my .Net code so that I get the intended value for listOfHolds?
Can I suggest any change to the owner of the Java web service?
[Optional] Why NumberOfHolds is being successfully read from the response but not listOfHolds?
The vendor of the web service has made a change. They changed xsi:type="ns0:holdDetails" to xsi:type="ns0:HoldDetails" (H instead of h).
The point is in Java, and unlike .Net as far as I can tell, they have a control over the generated XML from the web service.
I have wrote about a way to customize namespaces and namespace prefixes in a SOAP message generated by wcf here.
However, I can't find a proper method to override in the Message class in order to customize the SOAP headers of the messages.
I want to make this message:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<h:Protocol xmlns="http://www.xyz.de/Protocol" xmlns:h="http://www.xzy.de/Protocol">
<version>IFD_1.4</version>
</h:Protocol>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</s:Body>
</s:Envelope>
Look like this:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<if:Protocol xmlns="http://www.xyz.de/Protocol" xmlns:if="http://www.xzy.de/Protocol">
<version>IFD_1.4</version>
</if:Protocol>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</s:Body>
</s:Envelope>
The difference is that the namespace of the first header is "if" instead of "f".
Is there any way to do this using a custom MessageFormatter with a custom Message class ?
The solution I found is to derive from MessageHeader class and use it in my custom Message class (see link from question to see how I used the custom Message class to customize the envelope and body start tag).
I will update the answer with a full example once it will be ready.
If you have different solutions for this, please post it as the simpler answer which works without breaking the functionality of wcf will be selected.
You could use a custom MessageEncoder and in the ReadMessage and WriteMessage methods you can do whatever you like with the xml.
I have created a solution.
Added the WSDL file.
This keeps on popping following error "Length Required".
I tried with the above code in the post (, but seems that is not working.
Where do we specify the Operation name here?
-- Anand
Before getting it to work in java c# .net etc you need to get the SOAP xml correct.
The operation name is added as a tag in the soap body element.
Say for example your operation name is createMyOTRSTicket as specified in OTRS UI Web Service.
The SOAP request sent should look something like this like this:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<createMyOTRSTicket xmlns="WS">
<UserLogin>MyUserName</UserLogin>
<Password>MyPassword</Password>
<Queue>'some queue name'</Queue>
<State>'some state name'</State>
<Priority>1</Priority>
<!-- ...etc.. -->
<Article>
<Subject>some subject</Subject>
<Body>some body</Body>
<ContentType>text/plain; charset=utf8</ContentType>
</Article>
</createMyOTRSTicket >
</soap:Body>
</soap:Envelope>
See the API for what elements are require and which are optional for TicketCreate here
The Soap Message should be sent to /nph-genericinterface.pl/Webservice/CreateTicketWS where CreateTicketWS is the name of the Web Service.
Also note that the attribute xmlns="WS" refers to the Namespace you specify in "Network Transport" config also locatred in the GenericInterface Web Service Management.
I hope this helps you. Sorry it might be a bit confusing for someone new to SOAP and OTRS.