Coldfusion SOAP request preview - asp.net

I need to consume a asp.net web service using ColdFusion 8 and return an XML file.
I am able to communicate with asp.net service but am returned an error from the service that basically says the information I passed was not valid.
Here is a run down of my code :
<cfxml variable="soap">
<?xml version="1.0" encoding="UTF-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<cfoutput> <GetSession xmlns="#stagingurl#"></cfoutput>
<strApplicationKey>myappkey</strApplicationKey>
<UID>myuserid</UID>
<arrProperties>
<Property>
<Name>IP</Name>
<Value>127.0.0.1</Value>
</Property>
</arrProperties>
<arrRoles />
</GetSession>
</soap:Body>
</soap:Envelope>
</cfxml>
<cfhttp url="#apiurl#" method="post" result="httpresponse" port="443">
<cfhttpparam type="header" name="content-type" value="text/xml">
<cfhttpparam type="header" name="SOAPAction" value="#mysoapaction#">
<cfhttpparam type="header" name="content-length" value="#len(trim(soap))#">
<cfhttpparam type="header" name="charset" value="utf-8">
<cfhttpparam type="Body" value="#trim(soap)#" name="FileContent"/>
</cfhttp>
<cfdump var="#GetHttpRequestData()#" label="Get Http Request Data" />
Is there a way to preview the information being sent to make sure that ColdFusion is actually sending my XML/SOAP request?
I did use #GetHttpRequestData()# to return some data and within the structure, content is "empty string" and this is where I need help. Should this be empty? This is new for me, but, I guess I expected that my information being passed to the asp.net service would be in there.
FYI - I can see the HTTP and SOAP response fine, I just can not see the request information. How do I view the Request information?
Still trying to determine if the issue is on my end, or theirs and need to gather facts at this point.

Another invaluable tool when working with web services is soapUI. That should definitely be a part of your toolkit as well. You can build your request using soapUI and check the responses. Once you have it working with soapUI you can copy your request into your ColdFusion code.
One thing that I noticed is that your are wrapping your XML in a cfxml tag. I'm not sure if that is messing with your request or not. I typically wrap my XML request in cfsavecontent tags. So you could try changing your code like this:
<cfsavecontent variable="soap">
<?xml version="1.0" encoding="UTF-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<cfoutput> <GetSession xmlns="#stagingurl#"></cfoutput>
<strApplicationKey>myappkey</strApplicationKey>
<UID>myuserid</UID>
<arrProperties>
<Property>
<Name>IP</Name>
<Value>127.0.0.1</Value>
</Property>
</arrProperties>
<arrRoles />
</GetSession>
</soap:Body>
</soap:Envelope>
</cfsavecontent>
The rest of your code can remain the same.

If you're on Windows (or have a windows machine to hand) install Fiddler and start it. It's a proxy that listens on port 8888 by default so in your cfhttp call, add proxyServer="127.0.0.1" and proxyPort="8888" and run your request again.
Just noticed that you're using port 443, so probably SSL. You can enable HTTPS decrypt Tools->Fiddler Options->HTTPS Tab->Decrypt HTTPS traffic. You may then also need to import the Certificate that Fiddler uses into your keystore.
Each request will now show up in Fiddler and you can use the request and response inspectors on the right to look at the exact data going between the servers (the Raw tab shows the data unchanged). This has saved me so many times and is now part of my standard toolkit.
In your particular case, is there a reason you're not using CreateObject("webservice","http://....") . I'm assuming that it's not playing well with a .Net-based webservice?
Also, the call to GetHttpRequestData() shows the request you made to your test page, not the HTTP call you made to the test webservice. Unfortunately, CFHTTP doesn't return any structure showing the full HTTP request details it used. I think that would be a pretty sound feature request, as at the moment, you'll have to use a tool like fiddler or wireshark to see what was sent.

Simple issue with dot net is, it cannot processs XML document created by coldfusion. To return XML to dot net, convert into string format (XMLvariable.Tostring)
param of HTTP request should be
<cfhttpparam type="Body" value="#trim(soap).ToString#" name="FileContent"/>

Related

Difference between soap and xml over http?

I understand that we can encode any object in xml and send the xml in post request over http.So What extra advantage did we have using soap and why it became popular.
Your question is very generic and broad, hence there could long discussion/debate on whether SOAP is popular, and its pros vs cons. Even not sure if its duplicate question.
I would like to answer it shortly.
Because SOAP is standard because accepted/published by W3.org, hence widely accepted, and XML RPC or just XML over HTTP is not, hence would be less acceptable to organizations/service providers/developers.
SOAP as per wiki
SOAP (originally Simple Object Access Protocol) is a messaging protocol specification for exchanging structured information in the implementation of web services in computer networks. Its purpose is to induce extensibility, neutrality and independence. It uses XML Information Set for its message format, and relies on application layer protocols, most often Hypertext Transfer Protocol (HTTP) or Simple Mail Transfer Protocol (SMTP), for message negotiation and transmission.
XML over HTTP as per wiki,
XML-RPC is a remote procedure call (RPC) protocol which uses XML to encode its calls and HTTP as a transport mechanism.1 "XML-RPC" also refers generically to the use of XML for remote procedure call, independently of the specific protocol. This article is about the protocol named "XML-RPC".
Hence, XML over HTTP is subset of SOAP.
Meaning, every SOAP transaction is also XML over HTTP/HTTPS, but every XML over HTTP/HTTPS can't be SOAP.
SOAP Example XML,
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
XML over HTTP example:
<array>
<data>
<value><i4>1404</i4></value>
<value><string>Something here</string></value>
<value><i4>1</i4></value>
</data>
</array>
I would suggest you to do googling to more details, both are wide topics and I think can't be 100% in stack-overflow answer.

Adding FaultRule to ServiceCallout

I have been trying to make sense of the Apigee Guide on Fault Handling (http://apigee.com/docs/api-services/content/fault-handling) but it is not making sense to me.
The following request can result in a 404 error from the target server. How do I correctly catch this fault?
<ServiceCallout async="false" continueOnError="false" enabled="true" name="CalloutSessionSignIn">
<Request variable="SignInRequest"/>
<Response>SignInResponse</Response>
<HTTPTargetConnection>
<URL>http://localhost/{service_name}/{request.formparam.session_id}/signin</URL>
</HTTPTargetConnection>
One of the possible solutions is in my blog Handling 404 backend response
One you do the solution described, you can generate appropriate response based on SignInResponse.status.code=404 condition.

Web Service Adding extra forward slash in SOAPAction

I am using SoapUI to test a .Net Web Service that will be consumed by a Java client application.
When I hook up my Web Service to SoapUI but updating the WSDL location and call one of the preset testing scripts, the Web Service fails with the following code
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: urn:mycode:us:gu:das:supplierengagement:v02:SupplierEngagement:/AppointSupplier.
at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
As you can see from the above error, the problem is with the SOAPAction parameter having an extra forward slash.
I am using the following attribute on the class:
<WebService(Namespace:= "urn:mycode:us:gu:das:supplierengagement:v02:SupplierEngagement:AppointSupplier")>
and the following attribute on the method call:
<WebMethod(MessageName:="appointSupplierRq")>
From these, .Net is adding the forward slash.
It must be possible to remove the forward slash that is automatically being generated.
From reviewing the code, creating mock samples and such I don't see the problem. Yes I do see the extra forward slash as you mention in your post however that is by design. That is how the ASMX service notes the method within the class to execute.
Now from your SOAP message and your WebService \ WebMethod attributes there is something out of sync. Your SOAP Header action should be
urn:mycode:us:gu:das:supplierengagement:v02:SupplierEngagement:AppointSupplier/appointSupplierReq
not
urn:mycode:us:gu:das:supplierengagement:v02:SupplierEngagement:/AppointSupplier
This leads me to believe either you haven't updated the SOAP UI project to the new generated WSDL. Try creating a new Project in SOAP UI pointing the WSDL file of the ASMX web service such as.
http://<web host>/SupplierEngagement.asmx?wsdl
And run the test methods. If this does not fix the issue please post (as an edit) the full class for the SupplierEngagement asmx file (you can omit the method content) as we are only really interested in the full setup.
I had a similar issue that was finally a permissions issues on the server side that was providing the forward slash error, but other things can be done to diagnose the problem
Can the SoapAction of a SOAP REQUEST be altered by interoperability issues between .NET and JAVA or a network/infraestructure proxy

WebDAV Response for a server error

When returning a 500 error response, i want to have a WebDAV XML response like:
<?xml version="1.0" encoding="utf-8" ?>
<D:error xmlns:D="DAV:">
<D:must-be-checked-in/>
</D:error>"""
But instead of <D:must-be-checked-in/> i need some property for "Internal server error" which i could not find in any of the related RFCs. Is there a standard webdav response for server errors? Or an empty response body is ok?
If you don't have anything more specific to tell, an empty response body is just fine.

Parsing a multipart SOAP response in Flex?

I have a Flex application that needs to grab reporting data from a JasperReports Server, through the JasperReports Server Web Services API. Flex Builder 3 does a nice job of generating the web services consumption code, with one exception. If you ask for a directory list or an accounting of report parameters, JR Server returns plain XML in the SOAP wrapper and Flex parses it just fine. However, if you ask for a report itself, whether in XML or PDF format, it comes back as a multipart MIME message with some descriptive XML as the first part and the report -- even if the report itself is XML -- as the second part. Flex doesn't know what to do with multipart messages and just complains about invalid XML.
Here's a sample of the response. My current strategy is do some string parsing and manage the bits individually. But does Flex have any built-in methods to handle this? (I've been unable to find any.)
------=_Part_2_27050467.1235668849951
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <0F082AF1DAF83B3077B1867B4FC8AAA6>
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:runReportResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://axis2.ws.jasperserver.jaspersoft.com">
<runReportReturn xsi:type="xsd:string"><?xml version="1.0" encoding="UTF-8"?>\n<operationResult version="2.0.1">\n\t<returnCode><![CDATA[0]]></returnCode>\n</operationResult>\n
</runReportReturn>
</ns1:runReportResponse>
</soapenv:Body>
</soapenv:Envelope>
------=_Part_2_27050467.1235668849951
Content-Type: application/pdf
Content-Transfer-Encoding: binary
Content-Id: <report>
%PDF-1.4\n%âãÏÓ\n1 0 obj <</Filter/FlateDecode/Length 29>>stream\nx+är\ná26S°00S\bIár\rá\näâ
What I am going to say is only what I believe:I may be wrong since I haven't tried this out.
I don't think you have much choice. Flex HTTPService (or whatever you are using) can offer only so many (/or so few) data formats. See here. For any custom stream you will have to retrieve it as an object and pass it through your own decoder. It appears that Flex does not do any parsing of the MIME message but depends on (which is also how browsers behave typically) the server to identify the content that is being transmitted. If the server only sends a text file but changes the content type to say audio/mpeg I think you will have the same problem. Even when Flex does know hot to handle text.
If you ever can get around to doing this experiment (with text files as MIME type video or whatever fancies you) do let us know.
Meanwhile, you can take a look at SerializationFilter and go on and add a new MIME type for PDF!
Hopefully, life will be a little easy with Flex 4 and the HTTPMultiService.

Resources