I am accessing a third party Web based API Travelport. It was working fine on pre-production credentials and URL until we decided to go to production. First i had this charset=ISO-8859-1 issue which is solved by the help of Connecting to a PHP Web service with WCF in C# But now i am getting this exception
Server returned an invalid SOAP Fault. Please see InnerException for more details.
- Start element 'faultcode' from namespace '' expected. Found element 'SOAP-ENV:faultcode' from namespace 'http://schemas.xmlsoap.org/soap/envelope/'. Line 1, position 135.
This is the XML in my web_messages.svclog
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>0</EventID>
<Type>3</Type>
<SubType Name="Information">0</SubType>
<Level>8</Level>
<TimeCreated SystemTime="2015-07-06T07:43:46.8130015Z" />
<Source Name="System.ServiceModel.MessageLogging" />
<Correlation ActivityID="{992e2e7a-6cd7-475c-8b1f-684b90329a80}" />
<Execution ProcessName="iisexpress" ProcessID="5368" ThreadID="24" />
<Channel />
<Computer>PRODUCTION-2</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<MessageLogTraceRecord Time="2015-07-06T11:43:46.7920015+04:00" Source="TransportReceive" Type="System.ServiceModel.Channels.StreamedMessage" xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
<HttpResponse>
<StatusCode>InternalServerError</StatusCode>
<StatusDescription>Internal Server Error</StatusDescription>
<WebHeaders>
<Connection>close</Connection>
<Content-Length>554</Content-Length>
<Content-Type>text/xml;charset=ISO-8859-1</Content-Type>
<Date>Mon, 06 Jul 2015 07:46:08 GMT</Date>
<Server>Apache-Coyote/1.1</Server>
</WebHeaders>
</HttpResponse>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header></SOAP-ENV:Header>
<SOAP-ENV:Body>... stream ...</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</MessageLogTraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
I got this guy having the same problem but i am unable to apply this solution, I am new to WCF Please help me solve this issue
Update
After utilizing IClientMessageInspector and implementing it in custom class i am able to get this SOAP details
<SOAP-ENV:Fault xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">
<SOAP-ENV:faultcode>500</SOAP-ENV:faultcode>
<SOAP-ENV:faultstring>EntGWConnectServlet:29d64cb14e628c682c7b50 - Internal Error: nullnull</SOAP-ENV:faultstring>
<SOAP-ENV:faultactor></SOAP-ENV:faultactor>
<SOAP-ENV:detail>EntGWConnectServlet:29d64cb14e628c682c7b50 - Internal Error: nullnull</SOAP-ENV:detail>
</SOAP-ENV:Fault>
Still not able to get the exact error
As i mentioned above, after applying the solution i am still not getting the proper error so that i can rectify it.
Related
I am using Sabre SOAP Api in C#. I got the response from session creation successfully, I added wsdl Service Reference
http://files.developer.sabre.com/wsdl/sabreXML1.0.00/ServicesPlatform/PassengerDetails3.3.0RQ.wsdl to my test project and pass required values to parameters in the request as given in the documentation https://developer.sabre.com/docs/read/soap_apis/management/itinerary/Passenger_Details.
this is my xml to that is send to sabre and Getting Exception
<?xml version="1.0" encoding="utf-16"?>
<PassengerDetailsRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.2.1"
IgnoreOnError="false">
<MiscSegmentSellRQ xmlns="http://services.sabre.com/sp/pd/v3_2">
<MiscSegment DepartureDateTime="2018-01-10T16:45" InsertAfter="0" NumberInParty="1" Status="HK" Type="OTH">
<OriginLocation LocationCode="SAN" />
<Text>America Tours</Text>
<VendorPrefs>
<Airline Code="DL" />
</VendorPrefs>
</MiscSegment>
</MiscSegmentSellRQ>
<PostProcessing xmlns="http://services.sabre.com/sp/pd/v3_2">
<EndTransactionRQ>
<EndTransaction Ind="true">
<Email Ind="true" />
</EndTransaction>
<Source ReceivedFrom="SWS TESTING" />
</EndTransactionRQ>
</PostProcessing>
<PreProcessing xmlns="http://services.sabre.com/sp/pd/v3_2" />
<PriceQuoteInfo xmlns="http://services.sabre.com/sp/pd/v3_2">
<Link NameNumber="1.1" Record="1" />
</PriceQuoteInfo>
<SpecialReqDetails xmlns="http://services.sabre.com/sp/pd/v3_2">
<SpecialServiceRQ>
<SpecialServiceInfo>
<SecureFlight>
<PersonName DateOfBirth="02/02/1998" NameNumber="1.1">
<GivenName>Usama QW</GivenName>
<Surname>Alam</Surname>
</PersonName>
<VendorPrefs>
<Airline />
</VendorPrefs>
</SecureFlight>
</SpecialServiceInfo>
</SpecialServiceRQ>
</SpecialReqDetails>
<TravelItineraryAddInfoRQ xmlns="http://services.sabre.com/sp/pd/v3_2">
<AgencyInfo>
<Address>
<AddressLine>America Tours</AddressLine>
<CityName>Los Angeles</CityName>
<CountryCode>US</CountryCode>
<PostalCode>90020</PostalCode>
<StateCountyProv StateCode="CA" />
<StreetNmbr>3434 West 6th Street Suite 400-6</StreetNmbr>
</Address>
<Ticketing TicketType="7T-A" />
</AgencyInfo>
<CustomerInfo>
<ContactNumbers>
<ContactNumber NameNumber="1.1" Phone="213-738-8185" PhoneUseType="A" />
<ContactNumber NameNumber="1.1" Phone="3162881034" PhoneUseType="A" />
</ContactNumbers>
<Email Address="www.usamaalam60#gmail.com" ShortText="AmericaTours" />
<Email Address="admin#koreaonly.com" ShortText="AmericaTours" />
<PersonName NameNumber="1.1" NameReference="MR" PassengerType="ADT">
<GivenName>Usama sd</GivenName>
<Surname>Alam</Surname>
</PersonName>
</CustomerInfo>
</TravelItineraryAddInfoRQ>
</PassengerDetailsRQ>
For this one you seem to be using invalid service version for the 3.2 namespace. Try with something like this:
*xmlns="http://services.sabre.com/sp/pd/v3_2"* and *version="3.2.0"*.
You were using version 2.2.1 here which will require a different URL.
Are you intending to use 3.2.0 version? I can see that the dates are not valid as per the schema as well. You have:
*DateOfBirth="02/02/1998"*
but should have:
*DateOfBirth="1998-02-02"*
I was wondering how to consume a XML Service, which states: "CarTrawler’s OTA Server does not expose a Web Services interface - i.e. no SOAP-discoverable WSDL. All messages are stateless and no session is maintained between calls.".
The service have targets URL’s defined in order to send the requests.
One possible request may be:
<?xml version="1.0" encoding="UTF-8"?>
<OTA_VehAvailRateRQ
xmlns="http://www.opentravel.org/OTA/2003/05"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_VehAvailRateRQ.xsd"
Target="Test" Version="1.005">
<POS>
<Source ISOCurrency="EUR">
<RequestorID Type="16" ID="#####" ID_Context="####" />
</Source>
</POS>
<VehAvailRQCore Status="Available">
<VehRentalCore PickUpDateTime="2016-04-01T07:00:00" ReturnDateTime="2016-04-09T19:00:00">
<PickUpLocation CodeContext="####" LocationCode="71" />
<ReturnLocation CodeContext="####" LocationCode="71" />
</VehRentalCore>
<DriverType Age='30'/>
</VehAvailRQCore>
<VehAvailRQInfo PassengerQty='3'>
<Customer>
<Primary>
<CitizenCountryName Code='IE' />
</Primary>
</Customer>
<TPA_Extensions>
<ConsumerIP>999.999.999.999</ConsumerIP>
</TPA_Extensions>
</VehAvailRQInfo>
</OTA_VehAvailRateRQ>
Maybe using HttpClient?, as it has no WSDL and I guess the service isn't REST.
This is no problem. WSDL is just metadata to help you figure out the kind of data you should send or receive. It doesn't mean that the service is not RESTful.
There are many tools that you can use to call a RESTful service. This is my REST client:
https://bitbucket.org/MelbourneDeveloper/restclient-.net
NuGet: Install-Package RESTClient.NET
You should try just doing a simple GET as a string and see what gets returned. If you post the Url of the API, I will try it.
When using WCF and C# in a project I get an exception, MesssageSecurityException, with the message "Security header is empty.". Here follows the response (according to MS Service Trace Viewer):
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true"></wsse:Security>
<wsa:Action>_WHAT_I_DID_</wsa:Action>
<wsa:RelatesTo>_MSG_ID_OF_REQUEST_</wsa:RelatesTo>
</soapenv:Header>
<soapenv:Body>
_CORRECT_BODY_
</soapenv:Body>
</soapenv:Envelope>
Indeed, the security header is "empty", but it is still correct accprding to the security header definition as far as I can tell.
I've also tried editing the bindings, but that doesn't seem to help as well. I also found a similar problem where enabling EnableUnsecuredResponse would help, but it doesn't here.
Here is the response according to SoapUI:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/>
<wsa:Action>_WHAT_I_DID_</wsa:Action>
<wsa:RelatesTo>_REQ_MSG_ID_</wsa:RelatesTo>
</soapenv:Header>
<soapenv:Body>
_CORRECT_BODY_
</soapenv:Body>
</soapenv:Envelope>
They are almost identical, except for how they close the security header. Which is interesting, but should not raise the exception?
I also found a similar problem where the solution was to create a custom message encoder and strip the entire security header, although this would work it is an extra unneeded step. Is that the only way to do it with .Net and WCF? Can't WCF handle security headers without content?
EDIT:
Clarification of the issue, is writing an encoder which drops the security header the only way to recieve and parse SOAP-messages with empty security headers using WCF?
EDIT2: Adding part of conf:
<binding name="NinjaBinding">
<security allowSerializedSigningTokenOnReply="true" enableUnsecuredResponse="true"
authenticationMode="UserNameOverTransport" requireDerivedKeys="false"
securityHeaderLayout="Lax" includeTimestamp="false" allowInsecureTransport="true"
keyEntropyMode="ClientEntropy"
messageProtectionOrder="SignBeforeEncryptAndEncryptSignature"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSecurityContextCancellation="false">
<localServiceSettings detectReplays="false" />
<secureConversationBootstrap _IDENTICAL_TO_ABOVE_
</secureConversationBootstrap>
</security>
<textMessageEncoding />
<httpsTransport />
</binding>
As far as I know, its configure to allow practically everything?
(Now I'm answering my own question since I've been able to elicit some kind of answer)
In short, no you cannot use WCF "out of the box" (ie through *.config) with application servers which provide empty security headers in responses. You have to implement an encoder which modifies messages to a format acceptable by the WCF-framework.
For more information read this blog which contains a quite good walkthrough of the encoder and its applications. This blog (another blog) also provides a code snippet capable of solving my issue, ie modifying the security header.
I wonder why MS and Oracle products never can co-exist peacefully :D
What is the easiest way to create a web service with XML response?
Use WCF to create the web service? (seems really complicated)
If i want to use WCF to create my web service, where do I start?
In your case, I would definitely use WCF with the REST binding (webHttpBinding) - and I would disagree about it being complicated to learn.
Check out these resources to get started:
MSDN WCF REST developer center
DotNet Rocks TV Show #135: Keith Elder Demystifies WCF
DotNet Rocks TV Show #122: Miguel Castro on Extreme WCF
Few links are available in this article. Hope they will help you -
http://social.msdn.microsoft.com/Forums/en/wcf/thread/b082d6de-d1e9-4e51-a0ab-0fe98d7003e6
The easiest way to create a web service with an XML response is, no kidding, to put an XML file on a standard web server and serve it as a static file.
I'm guessing you want something more flexible than that, though...
You've got several options, and WCF is at the more complex (but flexible) end of the spectrum. First question: what's your client? Are you writing it? Do you want to write a web service that can be consumed by other clients?
Do you want to use REST -- i.e. plain-old-XML (POX) over plain-old-HTTP? XML-RPC? SOAP?
WCF supports all of these, so this really depends on which clients you want to support.
Update: If you want to support XML-RPC, you could do worse than start with this implementation of XML-RPC for WCF by Clemens Vasters. I asked a question about this here.
It's actually pretty easy to create a WCF service. There are plenty of tutorials online.
As for returning xml, there are a few ways.
You can do this with an 'old school' SOAP web service by converting the xml to a string in the service and then convert back in the client. It's not pretty but it works.
An alternative, and the way I'd do it, would be to use WCF and create a data contract that maps your xml.
You can do some pretty good stuff with data contracts, like pass round datasets and custom types but this can sometimes limit the binding types you can use.
I just made a web service.
PHP server side code:
<?php // instantiate SOAP server
function sendXmlMsg($msg){
return $msg;
}
ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSD
$server = new SoapServer("mark.wsdl");
// Register exposed method
$server->addFunction('sendXmlMsg'); // generate captcha
//$server->addFunction('check_captcha'); // check captcha ID
$server->handle(); //?>
My WSDL file is
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='Msg91'
targetNamespace='http://localhost/webtest/test.wsdl'
xmlns:tns='http://localhost/webtest/test.wsdl'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<message name='sendXmlMsgRequest'>
<part name='msg' type='xsd:string'/>
</message>
<message name='sendXmlMsgResponse'>
<part name='Result' type='xsd:string'/>
</message>
<portType name='Msg91PortType'>
<operation name='sendXmlMsg'>
<input message='tns:sendXmlMsgRequest'/>
<output message='tns:sendXmlMsgResponse'/>
</operation>
</portType>
<binding name='Msg91Binding' type='tns:Msg91PortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='sendXmlMsg'>
<soap:operation soapAction='urn:xmethods-delayed-quotes#sendXmlMsg'/>
<input>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<service name='Msg91Service'>
<port name='Msg91Port' binding='tns:Msg91Binding'>
<soap:address location='http://localhost/webtest/test.php'/>
</port>
</service>
</definitions>
Client side PHP file:
<?php
$client = new SoapClient("mark.wsdl");
$params= array('HiT');
echo $client->__soapCall( 'sendXmlMsg', $params );
?>
I hope this will help you.
I have run into an exasperating problem getting a Java service client to communicate successfully with a WCF service. I have overcome many hurdles, and I believe that this is my last one. The problem boils down to how Java Axis + WSS4J seem to handle xml namespaces. The Java platform seem to be very rigid in what they expect for xml namespace prefixes, and as such, do not understand the WCF reply messages.
My problem in a nutshell is as follows. I have an xml response similar to the following from my WCF service:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1" u:Id="_3">http://tempuri.org/IProcessor/DoProcessingResponse</a:Action>
<h:CorrelationID xmlns:h="http://tempuri.org/">1234</h:CorrelationID>
<a:RelatesTo u:Id="_4">uuid:40f800a0-9613-4f4a-96c5-b9fd98085deb</a:RelatesTo>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<!-- WS-Security header stuff -->
</o:Security>
</s:Header>
<s:Body u:Id="_1">
<e:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<e:CipherData>
<e:CipherValue>NfA6XunmyLlT2ucA+5QneoawHm+imcaCltDAJC1mRZOSxoB6YGpDLY1FyVykPbPGDoFGUESLsmvvbD62sNnRrgE+AuKPo+1CD3DF4LfurRcEv9A50ba9V+ViqlrhydhK</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</s:Body>
</s:Envelope>
This response uses simple one-character namespace prefixes for most things, such as 's' for SOAP Envelope, 'a' for WS-Addressing, 'o' for 'WS-Security', etc. The Java client, namely WSS4J, seems to expect the following:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action soap:mustUnderstand="1" wsu:Id="_3">http://tempuri.org/IProcessor/DoProcessingResponse</wsa:Action>
<h:CorrelationID xmlns:h="http://tempuri.org/">1234</h:CorrelationID>
<wsa:RelatesTo wsu:Id="_4">uuid:40f800a0-9613-4f4a-96c5-b9fd98085deb</a:RelatesTo>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<!-- WS-Security header stuff -->
</wsse:Security>
</soap:Header>
<soap:Body u:Id="_1">
<xenc:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<xenc:CipherData>
<xenc:CipherValue>NfA6XunmyLlT2ucA+5QneoawHm+imcaCltDAJC1mRZOSxoB6YGpDLY1FyVykPbPGDoFGUESLsmvvbD62sNnRrgE+AuKPo+1CD3DF4LfurRcEv9A50ba9V+ViqlrhydhK</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>
Upon receipt of my response message, the Java client and WSS4J seem to want to look up elements by their own internal xml aliases, such as 'wsa' for WS-Addressing, and 'wsse' for WS-Security Extensions. Since neither of those namespaces are present in the actual response xml, exceptions are thrown.
I am wondering if there is any simple way to transform an xml document from one set of namespaces to another set using C#, .NET, and the System.Xml namespace. I've poked around with XmlNamespaceManager a bit, but it does not seem to fully support what I need...or at least, I have been unable to find any really useful examples, and am not fully sure how it works. I am trying to avoid having to write some heavy-duty process to handle this manually myself, as I do not want to drastically impact the performance of our services when called by a Java Axis/WSS4J client.
This particular problem seemed to stem from an old and buggy version of WSS4J. Newer versions do not seem to have this problem, and it is no longer an issue.