Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with webservice, encoding, and byte[]

Status
Not open for further replies.

liscio

Programmer
Jul 11, 2007
8
IT
Hello,
i'm writing a windows form application in delphi6. i need to call a method of a webservice to "upload" some binary files. So that i can call the method and upload 1 file, or 4 files, or X files (at a time)...
The webservice is written by me in asp.net 2.0 (C# on VS2008) so i can change it as i need.
In delphi, i've imported the wsdl, and automatically created the interface to the webservice... then, placed the HTTPRIO component to connect.
I've tested passing some "test" strings, and works.

Now, i need to pass the binary data, to the webservice.

if i send an "simple" array of byte, it works fine... i'm running on loal network, so it's very fast... but i have to send a "variable" number of files, so in the webmethod (C#) i've declared the parameter as a bi-dimensional byte array (byte[][]) and re-generated the delphi interface unit for it.
Delphi mapped the type as:
ArrayOfBase64Binary = array of TByteDynArray

I read the files and populate an array of TByteDynArray, each TByteDynArray contains a single file.

When i call the webmethod, passing the "ArrayOfBase64Binary" as parameter, it works... but there is a strange behaviour: if i send just a couple of kbytes (100kb) it takes really a lot of time! during this time, i have the delphi process at 100% of cpu, and no-packet ove the network... i tried to send just 1 megabyte, waited for 15 minutes, then i stopped it. trying with other size, it looks the time increasing exponentially...

So, i was trying to send them in a serialized (XML) structure... created the delphi class, with list of files, each file with its binary data, and then serialized it as XML and stored in a widestring... i've modified the webservice to read the string and deserialize it. But when i call the webmethod from delphi, i have this exception:
an invalid character was found in text content
i think it's a problem of delphi encoding, but i don't know how to solve it.

Anyone can help me, please?

Thanks a lot...

Andrea
 
Are you sending the raw binary data in the XML? because that will never work. You need to encode the binary data in base64 format, ensuring you have safe characters for the SOAP message. The webservice must do the decoding part...

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
hi!
thanks for reply...
In delphi, i'm reading the file with blockread to a TByteDynArray variable, then i have an array of TByteDynArray and i pass it to the method...
What do you meand with "encode the binary data in base64 format"?

thanks

Andrea
 
explanation of base64 here:


how to encode in delphi, see here:


how to decode in .NET see here:


google is your friend :)

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
yeah, i know that google is my friend... i've spent the whole day, yestarday, searching it... but i thought your reply was about the first solution (bi-dimensional array of bytes)... instead, your reply is about the 2nd solution, you mean the encoding of the string-serialized XML structure with byte[] inside...
Sorry for misunderstanding.

Thanks a lot

Andrea
 
It's still not clear for me what exactly you are sending to the WS.
Do you have a form of encoding or not? (ie are you putting the EXACT file bytes into the SOAP message)?

The there is this other thing, have you thought about file size limitations? there are several limitations on the ASP.NET side you must take into account...

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
another option could be:

drop ASP.NET and do your uploads via FTP.

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Hi,
ftp is not suitable... the upload of the files is just a little part of the process, i have a complex website, and i need to call its webservices and pass it a lot of other information (other then the attachments) and i'd like the process to be strictly syncronous.

I have a good skill about asp.net and i know about file sizes etc... anyway, the extimated total size of each calling is less than 1mbyte, i know how to properly set timeouts and request lengths.

Thanks!
 
Ok, understood, but please answer my other question :)

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Hello,
I'm sending to the WS the content of some files... the type, number, and size of these files is variable.

In the 1st solution (bidimensional array) i'm putting in the first dimension of the array, the exact TByteDynArray of the bytes read from each file.

In the 2nd solution (explicit xml serialization) i'm putting, into the node-value, the exact TByteDynArray of the bytes read from each file.

I've tested the encoding to base64 but it doesn't work... i think i've messed up something in the test enviroment...
Anyway, at the moment, i found a workaround... i had to solve the issue in very short time, since i have to deploy it on tuesday.
Then, i will test and investigate the "right" way to solve the issue (working with base64) during the next week.

The workaround, is to add a paramter to the webmethod, explicitly declaring it with the type of its class... so, the delphi wdsl importing tool, created the implementation of that complex type (as a class(TRemotable)) inside the unit (the unit generated with the mapping to the webservice).
Then, i simply write the exact bytes of each file, putting the TByteDynArray content into the instances of that delphi class.
In this way, the serialization is implicit in the SOAP-message creation, and it's automatically done by delphi, in trasparent way.
It seems to work good.

Thanks a lot

Andrea
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top