Copy link to clipboard
Copied
I'm currently working on code to consume a soap webservice in cf8. I have most of the
implementation working and am able to use several of the methods defined in this
particular WS without issue. I'm having a problem with a particular function that
sends a PDF document to the WS. In the WS docs it lists the document 'content'
field as needing to be base64binary and from talking to the developers they say it
specifficly needs to be a byte array of base64binary.
Here's a snippet of the coldfusion code I'm using:
<cffile action="readbinary" file="#arguments.filepath#" variable="documentBinaryData"/>
<cfsavecontent variable="soapBody">
<cfoutput>
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<AddDocument xmlns="http://idoccentral.com">
<IKey>#arguments.iKey#</IKey>
<documentDetail>
<Source>#arguments.source#</Source>
<FolderID>#arguments.folderID#</FolderID>
<DocumentID>0</DocumentID>
<DisplayName>#arguments.displayName#</DisplayName>
<DocumentDescriptionID>0</DocumentDescriptionID>
<DocumentDescription>#arguments.documentDescription#</DocumentDescription>
<FileType>#arguments.fileType#</FileType>
<Content>#BinaryEncode(documentBinaryData,"Base64")#</Content>
</documentDetail>
</AddDocument>
</soap:Body>
</soap:Envelope>
</cfoutput>
</cfsavecontent>
<cfhttp url="http://stage.doccentral.trpoint.com/DCWebService/IDCService.asmx" method="post" result="httpResponse" timeout="600" throwonerror="yes">
<cfhttpparam type="header" name="SOAPAction" value="http://idoccentral.com/AddDocument"/>
<cfhttpparam type="header" name="accept-encoding" value="no-compression"/>
<cfhttpparam type="xml" value="#trim(soapBody)#"/>
</cfhttp>
The WS response is telling me that everything was ok, I can see the file on the
remote system but when i try to view it from there i get a corrupt file as if my encoding
is incorrect or they are not decoding it correctly.
I've used this same method before for a different web service that also recieves
base64binary encoded PDF documents and it's working just fine there.
As far as i can tell im encoding it to base64Binary correctly, not sure about the
byte array part but im assuming thats whet the cffile readbinary is returning.
Am i doing something wrong in my code or is it more likely to be something on
their end or something wrong in my header?
1 Correct answer
it is only 545 bytes
Hmm... are the resulting files always that small? Crazy thought, but open the tiny file with notepad or something. Just to see if even looks like a truncated pdf. They usually start with %PDF-(version number).
Also you might sniff the traffic to see what your full soap request looks like. See how it compares to their sample
http://stage.doccentral.trpoint.com/DCWebService/IDCService.asmx?op=AddDocument
...
The main point of this posting was to find out if my encoding method was wro
Copy link to clipboard
Copied
...the developers they say it specifficly needs to
be a byte array of base64binary.
Something about that description feels "off". But if you mean an array of bytes converted to a base64 string, nothing about your code jumps out at me as being glaringly wrong.
The WS response is telling me that everything was ok,
Does the content-length line match up with your request size?
when i try to view it from there i get a corrupt file
How are you accessing the file, directly or with another web service call? Could the problem be with the code used to view/retrieve the file?
Message was edited by: -==cfSearching==-
Copy link to clipboard
Copied
This is for an MLS Realtor service. It allows them to put their documents up so their clients can access them easily.
I have a development account on the staging server that i can log into and download the files. Seems to be just a simple http file download.
I'll have to check the content length thats something i haven't really had to look at before.
I've done a couple of web service projects in CF but im still learning some of the ins and outs.
Copy link to clipboard
Copied
log into and download the files that i have sent in. Seems
to be just a simple http file download.
Oh, I thought it might be something more complex. I still do not see anything obviously wrong with the code. Unless the definition of byte array base64binary is different than what we are thinking it is ..
Did you check the basics like file size? How does the final file compare to the original - smaller, larger, same .. ? Also, I assume the issue occurs with every file, not just certain types, etcetera... ?
Copy link to clipboard
Copied
Yeah I'm not doing anything fancy with the WS, just basically authenticating
and then calling the addDocument method to send the PDF content.
Their system only accepts PDF format, the file type param is useless, so i haven't
tried any other file types. I have tried it with multiple different PDF files just to make
sure it wasn't a broken or non standard file coming from my end.
I just did a compare on file size and the original file was 123k, resulting file on
their server when i download it is only 545 bytes so yeah it's completly fubar at
that point. You would think even with an improper encode or decode that the
result file would be a lot bigger then that.
Do you think maybe i need to pass a content length in my header? The reason
I'm doing the whole cfsavecontent cfhttp method is because i tried it as a cfInvoke
on the webservice and couldn't manage to get it working by simply building out a
struct to pass in and letting CF handle all the XML internaly, it would always come
back and tell me that it couldn't find a method called addDocument with those
params. The cfinvoke webservice is however working ok for the other WS method
i need to call in order to get my auth key.
I'm beginning to think the problem lies on their end, it's been very difficult and slow
going to get ahold of somebody over there to help me though. The main point of this
posting was to find out if my encoding method was wrong, from what i can tell theres
not really another way to do that encoding in CF though.
Copy link to clipboard
Copied
it is only 545 bytes
Hmm... are the resulting files always that small? Crazy thought, but open the tiny file with notepad or something. Just to see if even looks like a truncated pdf. They usually start with %PDF-(version number).
Also you might sniff the traffic to see what your full soap request looks like. See how it compares to their sample
http://stage.doccentral.trpoint.com/DCWebService/IDCService.asmx?op=AddDocument
The main point of this posting was to find out if my encoding method was wrong
Unless I am misunderstanding what is meant by base64binary.. I do not think so. Your code looks correct to me.
The reason I'm doing the whole cfsavecontent cfhttp method is because i tried it as a cfInvoke on the webservice and couldn't manage to get it working by simply building out a struct to pass in and letting CF handle all the XML internaly, it would always come back and tell me that it couldn't find a method called addDocument with those params.
Out of curiosity, what did you try? It does not look too complicated (famous last words I know ...)
Copy link to clipboard
Copied
Ah.. I see it is lunch time for the jive forums!
-Leigh
Copy link to clipboard
Copied
I did look at the file contents for the corrupted pdf and it looked like complete garbage.
there was no PDF at the start like I see when I look at the orignal file.
The other way that i had tried invoking the WS was like this.
<cffile action="readbinary" file="c:\somefile.pdf" variable="documentBinaryData"/>
<cfset args.IKey="my ikey from previous WS call">
<cfset args.documentDetail.Source="My Website">
<cfset documentDetail=structNew()>
<cfset documentDetail.FolderID="1234">
<cfset documentDetail.DocumentID="0 for a new document">
<cfset documentDetail.DisplayName="Document Name">
<cfset documentDetail.DocumentDescriptionID="0 for a new description">
<cfset documentDetail.DocumentDescription="Document Description">
<cfset documentDetail.FileType="pdf">
<cfset documentDetail.Content=BinaryEncode(documentBinaryData,"Base64")>
<cfinvoke
webservice="http://stage.doccentral.trpoint.com/DCWebService/IDCService.asmx?wsdl"
method="addDocument"
returnvariable="dcSvc">
<cfinvokeargument name="IKey" value="#getIkey.iKey#">
<cfinvokeargument name="documentDetail" value="#documentDetail#">
</cfinvoke>
This results in a CF error "Web service operation addDocument with parameters
(bunch of long params that all look correct) cannot be found". It's odd because im using
this method successfully for one of the other function calls to create a folder and it's using
a structure for the folder data which is very close to the document detail struct
I'm going to do some extended tracing today and I'm, hopefully, going to hear from the devs
so i can get this straightened out. Thanks for you suggestions, I think you've helped me
answer my basic questions.
Copy link to clipboard
Copied
This results in a CF error "Web service operation addDocument with parameters (bunch of long params that all look correct) cannot be found". It's odd because im using this method successfully for one of the other function calls
Weird. I pulled down the wsdl locally and at first I got the same " ... cannot be found" error with CF9. I was curious if the "Content" parameter was the source of the problem, so I removed it from the "Document" definition and refreshed the wsdl.
<s:element minOccurs="0" maxOccurs="1" name="Content" type="s:base64Binary"/>
As I expected, the cfinvoke call started working after that. Do not ask me why, but now even a direct call to http://stage.doccentral.trpoint.com/DCWebService/IDCService.asmx?wsdl seems to work. Even after I deleted the stubs and restarted CF. Obviously I cannot run a real test without a key. But the "..cannot be found" error went away and I do get a valid xml response. Weird...
Copy link to clipboard
Copied
Well I finaly got the cfinvoke method to work as well. still not getting a vaild file though.
The code below should handle base64 encoding of the documentBinaryData from a
binary byte array automaticly based on the WSDL. Also isn't base64 encoding pretty
standard as an XML safe way of passing binary data?
<cffile action="readbinary" file="c:\somefile.pdf" variable="documentBinaryData"/><cfset documentDetail=structNew()><cfset documentDetail.Source="Source Application Name"><cfset documentDetail.FolderID="1234"><cfset documentDetail.DocumentID="0 for a new document"><cfset documentDetail.DisplayName="Document Name"><cfset documentDetail.DocumentDescriptionID="0 for a new description"><cfset documentDetail.DocumentDescription="Document Description"><cfset documentDetail.FileType="pdf"><cfset documentDetail.Content=documentBinaryData><cfinvoke webservice="http://stage.doccentral.trpoint.com/DCWebService/IDCService.asmx?wsdl" method="addDocument" returnvariable="dcSvc"> <cfinvokeargument name="IKey" value="My Ikey"> <cfinvokeargument name="documentDetail" value="#documentDetail#"></cfinvoke>
Here a snip of what i got back as a response after i sent them a SOAP trace.
"I had our developer look at the soap trace and test the xml, he pointed out that
looking at the trace, it seems like the document is encoded to base64 format but
is sent as a string and not as a byte array."
I did a bunch of testing and research again today and from what i can tell the readbinary
action is returning a byte array so i donno what the heck the developer is smoking
or why their WS won't accept my encoding correctly.
Copy link to clipboard
Copied
OK we can put this to rest. I finally got it to work. Apparently they needed the base 64
encoded string to be further encoded into sequence of bytes. so basically all i needed to
do was use the java getBytes method on my string and then pass that in as the content.
Thanks again for your help trying to figure this out.
Copy link to clipboard
Copied
i donno what they heck
the developer is smoking
At the risk of sounding like I am smoking something, could they possibly mean they want you to base64 encode it and then convert it back into binary and send that?
Copy link to clipboard
Copied
Actualy that is pretty much what it was. goes binary file data to base 64 encoded string
then getBytes on that string which returns some sort of binary data it looked like.
Copy link to clipboard
Copied
Actualy thats is pretty much what it was.
Yep. I responded before I saw your last post. But good to have it confirmed. base64binary .. guess we should have been more literal 😉
then getBytes on that string which returns some sort of binary data
Yes, it should return binary just like your cffile read. As far as getBytes(), since there is a CF function for that already, I would use it instead. Granted either should work with the correct encoding.
Anyway, I am glad you finally got it working!

