We have a .NET Client with a Web Reference to a SOAP Based Web Service. The method we are calling has a signature string request() but when we call it we only ever receive a null value. The target service is receiving the request and responding with something other than null but our client only ever returns a null value
Looking at the WSDL, the response should be as follows:
<message name="requestResponse">
<part name="request" type="xsd:any"/>
</message>
The actual response looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="urn:pt_service" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2003/05/soap-encoding">
<env:Body xmlns:rpc="http://www.w3.org/2003/05/soap-rpc">
<ns1:requestResponse env:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<rpc:result>textnoenc</rpc:result>
<response>
<result>12</result>
<message><![CDATA[Bad]]></message>
<error>
<code>0</code>
<desc><![CDATA[Bad]]></desc>
</error>
</response>
</ns1:requestResponse>
</env:Body>
</env:Envelope>
It appears the target service is responding with something that is not defined in the WSDL resulting in the client returning a null value but I am not sure about that
Can anyone shed some light on what might be happening here?
Note: no exceptions have been experienced on the client
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.
I'm trying to update some WSE code to use WCF, and I'm running into trouble with one service in particular. When I generated my proxy class from the WSDL, it creates methods with no parameters or return type. The parameters were easy enough to fix -- saved the autogenerated References.cs file as a new file, added the parameter to both the generated interface and generated client, and it works. Using Fiddler, I can see that the traffic is as expected.
What I'm finding very vexing is that WCF seems to be just throwing away the response payload. I can see it coming back over the wire, but it seems to just vanish somewhere in the deep dark crevices of WCF. No errors or warnings, just gone.
I'm kind of at my wits end here. I'd really appreciate any suggestions on how to figure out where the response is going.
The method in the client (this used to return void; I've set it to object[] in hopes I could get something that I could cast):
public object[] getAddress(string user) {
return base.Channel.getAddress(user);
}
The method in the interface:
[System.ServiceModel.OperationContractAttribute(Action = "https://xxxxxx/Address#getAddress", ReplyAction = "*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
object[] getAddress(string user);
The raw XML response (redacted) looks something 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>
<getAddressResponse xmlns="https://xxxxx/Address">
<ArrayOfAddress arrayType="xsd:Address[3]" soapenc:arrayType="xsd:anyType[3]" xsi:type="Array">
<Address>
<street xsi:type="xsd:string">3rd</street>
</Address>
<Address>
<street xsi:type="xsd:string">1st</street>
</Address>
<Address>
<street xsi:type="xsd:string">2nd</street>
</Address>
</ArrayOfAddress>
</getAddressResponse>
</soap:Body>
Thanks in advance!
EDIT: I was unable to get this resolved, and there are only a few methods on this service, so I ended up just manually interacting with the service using WebClient, bypassing WCF.
Returning object[] isn't going to give you something you can cast. WCF on the client needs to know the possible concrete types to deserialize the response. I'd expect an exception though.
To fix this you should go ahead and create the Address data contract class.
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 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.