I am getting null response from sabre web service when call GetReservation Request
<GetReservationRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.18.0">
<Locator xmlns="http://webservices.sabre.com/pnrbuilder/v1_18">Its Unique </Locator>
<RequestType xmlns="http://webservices.sabre.com/pnrbuilder/v1_18">Stateful</RequestType>
<ReturnOptions xsi:type="ReturnOptions" xmlns="http://webservices.sabre.com/pnrbuilder/v1_18">
<ViewName>VaDefaultWithPq</ViewName>
</ReturnOptions>
</GetReservationRQ>
in this ReturnOptions tag one more element is missing is ResponseFormate that default value is STL so thats why it can not show on xml writing.
Is there a reason you are using "It's Unique" as a record locator? You should put a valid record locator there or delete the node if you are reading a PNR you have in your work area.
Can you post the Sabre endpoint you are pointing your application to?
Related
I have a C# project where I added a SOAP service reference, using the integrated visual studio functionality (right click -> add -> service reference)
The client classes are generated correctly without errors. However, the various methods of the service only accept a generic System.Xml.XmlNode as an input, rather than a structured object.
This should not be a problem in theory, since I have the complete XML file with the query that I need to perform. So I tried doing it like this:
NSIStdV20ServiceSoapClient client = new NSIStdV20ServiceSoapClient();
var getAllDataFlowQuery = File.ReadAllText(#"Query\get_all_dataflow.xml"); //file containing the query
XmlDocument doc = new XmlDocument();
doc.LoadXml(getAllDataFlowQuery);
var dataStructures = client.QueryStructure(doc); //this method accepts a System.Xml.XmlNode as parameter
However, this doesn't work, throwing
System.ServiceModel.FaultException: 'Error due to a non correct client message'
I thought initially that the query was incorrect, but I tried to perform the exact same query using SoapUI and it works perfectly! I even tried doing it with the exact XML returned by doc.InnerXml (just to be sure che XmlDocument object was not modifying the XML) and it works.
So basically it's only when calling the method from C# that it doesn't work.
If you want to try it out yourself, the service is freely accessible, the WSDL is here:
http://sdmx.istat.it/SDMXWS/NsiStdV20Service.asmx?WSDL
and you should try to call the QueryStructure method with the following payload:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://ec.europa.eu/eurostat/sri/service/2.0"><soapenv:Header /><soapenv:Body><web:QueryStructure><!--Optional:--><web:Query><RegistryInterface xsi:schemaLocation="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message SDMXMessage.xsd" xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message" xmlns:common="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/common" xmlns:compact="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/compact" xmlns:cross="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/cross" xmlns:generic="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic" xmlns:query="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query" xmlns:structure="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure" xmlns:registry="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/registry" xmlns:utility="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/utility" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Header><ID>JD014</ID><Test>true</Test><Truncated>false</Truncated><Name xml:lang="en">Trans46302</Name><Prepared>2001-03-11T09:30:47-05:00</Prepared><Sender id="BIS" /></Header><QueryStructureRequest resolveReferences="false"><registry:DataflowRef /></QueryStructureRequest></RegistryInterface></web:Query></web:QueryStructure></soapenv:Body></soapenv:Envelope>
As I said, this works perfectly in SoapUI, but doesn't work when calling the client method from C#
Well, it seems that the client generated by visual studio, even tho it accepts a XmlNode as input, creates some of the required outer structure itself (to be precise: all the outer nodes with the soapenv and web namespaces).
Which means I had to strip down the input XML to:
<?xml version="1.0" encoding="UTF-8"?><RegistryInterface xsi:schemaLocation="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message SDMXMessage.xsd" xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message" xmlns:common="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/common" xmlns:compact="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/compact" xmlns:cross="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/cross" xmlns:generic="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic" xmlns:query="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query" xmlns:structure="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure" xmlns:registry="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/registry" xmlns:utility="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/utility" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Header><ID>JD014</ID><Test>true</Test><Truncated>false</Truncated><Name xml:lang="en">Trans46302</Name><Prepared>2001-03-11T09:30:47-05:00</Prepared><Sender id="BIS" /></Header><QueryStructureRequest resolveReferences="false"><registry:DataflowRef /></QueryStructureRequest></RegistryInterface>
I am pretty new with web services and WSDLs.
What I want to do is to build a web service to read in a customer's SOAP message and process it.
The soap message sent to me is as follows (note I have trimmed the SOAP message right down)
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope">
<soap2:Header>
<wsa:Action>http://htng.org/PWSWG/2010/12/ReservationSynch_SubmitRequest</wsa:Action>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:ReplyTo>
</soap2:Header>
<Body>
<OTA_HotelResNotifRQ>
<POS>
//More tags
</POS>
<HotelReservations>
<HotelReservation RoomStayReservation="true">
<UniqueID Type="14" ID="59071IC000041" />
</HotelReservation>
</HotelReservations>
</OTA_HotelResNotifRQ>
</Body>
</Envelope>
This is my web service asmx (again I have trimmed it right down)
[WebMethod]
[SoapDocumentMethodAttribute("http://htng.org/PWSWG/2010/12/ReservationSynch_SubmitRequest", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
public OTA_HotelResNotifRS ReservationSynch_SubmitRequest(OTA_HotelResNotifRQ OTA_HotelResNotifRQ)
{
}
Problem: When the message comes in, the method ReservationSynch_SubmitRequest gets fired but OTA_HotelResNotifRQ is null. The customer gave me the WSDL, as far as am concerned the class is correct. Though I notice the <Body> tag and is not <soap2:Body>. Does this make a difference?
I cannot change customer's message, I can only change my web service to read what they have sent to me. Am I missing something in my asmx?
If you are interested, here is their WSDL https://interface.synxis.com/interface/ota2010av2/OTA2010A.svc.wsdl
Found the problem!
I changed the namespace for a couple of the classes, which affected the schema files in the WSDL.
We have been battling with a SOAP related problem for some time. We have a SOAP based API that can be called from a number of languages (PHP, Ruby etc). C#, however, seems to choke in certain circumstances.
Unfortunately, it is not clear to us why it dies. We are not C# people, but we did get an external, C# person to look at the problem. And, they were also baffled!
The wdsl can be seen here: http://sandbox.knowledgetree.com/ktwebservice/webservice.php?wsdl (yes, its large).
From C#, session creation, and several other calls work happily. However, the get_folder_contents call fails. The call executes, and fiddler shows valid XML being returned. However, C#'s return value is null.
The request, per Fiddler, is as follows:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<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">
<s:get_folder_contents>
<session_id xsi:type="xsd:string">or8llmjj5rm7co9h5p2k762s77</session_id>
<folder_id xsi:type="xsd:int">99</folder_id>
<depth xsi:type="xsd:int">1</depth>
<what xsi:type="xsd:string">DFS</what>
</s:get_folder_contents>
</s:Body>
</s:Envelope>
(I've added spaces and line breaks to the fiddler logs).
The response, per Fiddler (but, again, formatted for clairty), is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns4="urn:KnowledgeTree" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<SOAP-ENV:get_folder_contentsResponse>
<item xsi:type="ns4:kt_folder_contents">
<status_code xsi:type="xsd:int">0</status_code>
<message xsi:type="xsd:string"></message>
<folder_id xsi:type="xsd:int">99</folder_id>
<folder_name xsi:type="xsd:string">Nic</folder_name>
<full_path xsi:type="xsd:string">Nic</full_path>
<items xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="ns4:kt_folder_item[0]" xsi:nil="true"/>
</item>
</SOAP-ENV:get_folder_contentsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The (crude) C# application we used to test is as follows:
public partial class Form1 : Form
{
private string _sessionId;
private KnowledgeTreePortClient _webService;
public Form1()
{
InitializeComponent();
_webService = new KnowledgeTreePortClient();
_webService.loginCompleted += new EventHandler<loginCompletedEventArgs>(WebLoginCompleted);
_webService.loginAsync("username", "secret_password", "nil", "c-sharp-test");
}
private void WebLoginCompleted(object sender, loginCompletedEventArgs e)
{
_sessionId = e.Result.message;
_webService.get_folder_contentsCompleted += GetFolderComplete;
_webService.get_folder_contentsAsync(_sessionId, 99,1, "DFS");
}
private void GetFolderComplete(object sender, get_folder_contentsCompletedEventArgs e)
{
}
}
I'd prefer to fix this from the client (C#) side. But, any guidance as to what we are doing wrong would be much appreciated!
renen.
I tried it and got the same response.
The way I resolved it and got the response you're looking for is by adding a web reference instead. To do this right click on the references folder of your project, select add service service reference, click on the web reference button on the bottom and then proceed from there.
The proxy classes generated by that method behave as you'd expect.
As to why the service reference is not working I'm still looking into that....
EDIT:
So I've check the response Xml against the WSDL and I cannot spot any namespace mismatches. I found a couple of articles detailing how to resolve sub elements (like arrays) being null which was mostly because of a namespace mismatch - but in your case the whole kt_folder_contents value is bull and as far as I can see the namespace (urn:KnowledgeTree) in the generated wrappers is correct.
I hope someone else can give a fix for this - else if the Web Reference generated proxy works for you...
Not sure whether this makes a difference in view of the comments regarding true root cause but I have found that C#/VS interprets the entire return value as null when there is an array within the SOAP response that contains a xsi:nil="true"/> value as in:
items xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="ns4:kt_folder_item[0]" xsi:nil="true"/>
I am trying to consume the webservice in a WINFORMS application and responses without this array value seem to work fine but the two that show null return values in their response object both have the nil="true" for an array that is part of the object. Don't know if it's merely coincidence but appears to be related to comment on profile (WS-I BP1) compliance?
Alan
I came across this problem and the Web Reference proxy workaround that #QuintonBernhardt suggested worked for me. Just want to mention how to add Web Reference in recent Visual Studio versions (2017+):
In regular add service reference dialog, choose "Advanced"
Then in the compatibility section select "Add Web Reference"
I want to integrate with webservice writes in php (PEAR SOAP).
Wsdl file is without types definition.
When i was connect to webservice i getting a null response.
In WebServiceStudio i see xmlrequest and xmlresponse, my I get xmlresponse in c# default soap or other soap.
I know what is causing the null response. PEAR SOAP returnx STRUCT[X] as a response type, where X is number of list element.
When I my get XMLresponse and replace this section then it would be cool
Regards
Sorry for my english
The method you need is getLastResponse(), but if it's anything like other, similar HTTP-stream classes, you'll probably need to set a flag to enable capturing the raw requests/responses. Then again, maybe not, since you apparently have to use parseResposne to get the data out of the XML.
Try:
$soapClient->call(some,parameters,here);
$response = $soapClient->getLastResponse();
echo $response;
My web service method returns a collection object, this will serialize nicely, thanks to the way C# web services work!
But if my code throws an uncaught exception, I want to instead return a custom error object.
Is this possible using C# ASP.NET v2?
For example,
Normal Operation should return:
<Books>
<book>Sample</book>
<book>Sample</book>
</Books>
But on error I want
<error>
<errorMessage></errorMessage>
</error>
Yes, this is possible.
What you'll need to look into is the SoapException class, and specifically the Detail property of the SoapException class.
The SoapException class will effectively render a "Soap Fault", which is the standards-compliant mechanism for returning error information to clients/consumers from a web service method.
The "Detail" property of the SoapException class is of type XmlNode and can thus contain either a single node/element or a hierarchy of child nodes. The Detail node could therefore easily contain and act as the "parent" for the serialized representation of your own custom error object.
From MSDN:
The Detail property is intended for supplying application specific error details related to the Body element of the SOAP request. According to the SOAP specification, if an an error occurrs because the client request could not be processed due to the Body element of the SOAP request, the Detail property must be set. If an error occured in the header entries of the SOAP request, you must throw a SoapHeaderException, so that the error details are returned in the SOAP header. If the error did not occur, due to the processing of the Body element, then the Detail property must not be set.
In building an XmlNode for the Detail property, the Name and Namespace properties of DetailElementName can be used to ensure consistancy [sic] with the SOAP specification.
All immediate child elements of the detail element are called detail entries and each detail entry is encoded as an independent element within the detail element.
Note that if you wish to remain correctly SOAP compliant with your web service responses, you'll need to return a SoapHeaderException rather than a SoapException if the error occurs within the client's header section of the original XML request (this can often be the case when using custom SOAP headers for e.g. security credentials) as detailed above.