File Uploads to Web Service in both SOAP and HTTP-POST

B

Brybot

I am trying to allow HTTP POST file uploads to my web service.
Currently I have it working perfectly for a SOAP/XML request reading
in a byte[ ] using MemoryStream/FileStream but I cannot figure out how
to encode a file on a POST to the same web service. The definition
requires a base64binary encoded file, which I have tried. The form is
also using a mutlipart/form-data enctype, but I either get a 500 error
or 'Request format is invalid'. Is there a trick to serializing a
form so that the web service will accept it as a byte[ ]?

Alternatively, I would be happy to differentiate the methods used and
create the files accordingly, ie. if its done over SOAP/XML use my
current method, or if its a POST call, use HttpFileCollection or
something? Can you differentiate how a web service was called within
the service itself?
 
B

Brybot

I am trying to allow HTTP POST file uploads to my web service.
Currently I have it working perfectly for a SOAP/XML request reading
in a byte[ ] using MemoryStream/FileStream but I cannot figure out how
to encode a file on a POST to the same web service. The definition
requires a base64binary encoded file, which I have tried. The form is
also using a mutlipart/form-data enctype, but I either get a 500 error
or 'Request format is invalid'. Is there a trick to serializing a
form so that the web service will accept it as a byte[ ]?

Alternatively, I would be happy to differentiate the methods used and
create the files accordingly, ie. if its done over SOAP/XML use my
current method, or if its a POST call, use HttpFileCollection or
something? Can you differentiate how a web service was called within
the service itself?

Well it appears that if I convert to binary and separate each bit out
like &param=bit0&param=bit1&param=bit2 etc... it will work...
unfortunately these files are +1Gb. Is there a better way to do this?
 
J

John Saunders [MVP]

Brybot said:
I am trying to allow HTTP POST file uploads to my web service.
Currently I have it working perfectly for a SOAP/XML request reading
in a byte[ ] using MemoryStream/FileStream but I cannot figure out how
to encode a file on a POST to the same web service. The definition
requires a base64binary encoded file, which I have tried. The form is
also using a mutlipart/form-data enctype, but I either get a 500 error
or 'Request format is invalid'. Is there a trick to serializing a
form so that the web service will accept it as a byte[ ]?

Alternatively, I would be happy to differentiate the methods used and
create the files accordingly, ie. if its done over SOAP/XML use my
current method, or if its a POST call, use HttpFileCollection or
something? Can you differentiate how a web service was called within
the service itself?

Well it appears that if I convert to binary and separate each bit out
like &param=bit0&param=bit1&param=bit2 etc... it will work...
unfortunately these files are +1Gb. Is there a better way to do this?

XML Web Services are about XML. I don't think you're going to get files to
work the way you want to.

OTOH, WCF supports streaming data. See Large Data and Streaming
(http://msdn2.microsoft.com/en-us/library/ms733742.aspx), and How to: Enable
Streaming (http://msdn2.microsoft.com/en-us/library/ms789010.aspx).
 
B

Brybot

I am trying to allow HTTP POST file uploads to my web service.
Currently I have it working perfectly for a SOAP/XML request reading
in a byte[ ] using MemoryStream/FileStream but I cannot figure out how
to encode a file on a POST to the same web service. The definition
requires a base64binary encoded file, which I have tried. The form is
also using a mutlipart/form-data enctype, but I either get a 500 error
or 'Request format is invalid'. Is there a trick to serializing a
form so that the web service will accept it as a byte[ ]?
Alternatively, I would be happy to differentiate the methods used and
create the files accordingly, ie. if its done over SOAP/XML use my
current method, or if its a POST call, use HttpFileCollection or
something? Can you differentiate how a web service was called within
the service itself?
Well it appears that if I convert to binary and separate each bit out
like &param=bit0&param=bit1&param=bit2 etc... it will work...
unfortunately these files are +1Gb. Is there a better way to do this?

XML Web Services are about XML. I don't think you're going to get files to
work the way you want to.

OTOH, WCF supports streaming data. See Large Data and Streaming
(http://msdn2.microsoft.com/en-us/library/ms733742.aspx), and How to: Enable
Streaming (http://msdn2.microsoft.com/en-us/library/ms789010.aspx).

Its not the files that are the problems, you can stream the files just
fine through XML, its the method of form POSTing a file to an XML
webservice, which again is possible without changing a thing, but you
have to marshal the file into binary and send it 1 bit to a post
variable. I was just wondering if there is an easier way to marshal a
file through a POST then bit by bit. Otherwise we just use a base64
binary stream which the SOAP envelope delivers as a byte [ ].
 
J

John Saunders [MVP]

Brybot said:
I am trying to allow HTTP POST file uploads to my web service.
Currently I have it working perfectly for a SOAP/XML request reading
in a byte[ ] using MemoryStream/FileStream but I cannot figure out how
to encode a file on a POST to the same web service. The definition
requires a base64binary encoded file, which I have tried. The form is
also using a mutlipart/form-data enctype, but I either get a 500 error
or 'Request format is invalid'. Is there a trick to serializing a
form so that the web service will accept it as a byte[ ]?
Alternatively, I would be happy to differentiate the methods used and
create the files accordingly, ie. if its done over SOAP/XML use my
current method, or if its a POST call, use HttpFileCollection or
something? Can you differentiate how a web service was called within
the service itself?
Well it appears that if I convert to binary and separate each bit out
like &param=bit0&param=bit1&param=bit2 etc... it will work...
unfortunately these files are +1Gb. Is there a better way to do this?

XML Web Services are about XML. I don't think you're going to get files
to
work the way you want to.

OTOH, WCF supports streaming data. See Large Data and Streaming
(http://msdn2.microsoft.com/en-us/library/ms733742.aspx), and How to:
Enable
Streaming (http://msdn2.microsoft.com/en-us/library/ms789010.aspx).

Its not the files that are the problems, you can stream the files just
fine through XML, its the method of form POSTing a file to an XML
webservice, which again is possible without changing a thing, but you
have to marshal the file into binary and send it 1 bit to a post
variable. I was just wondering if there is an easier way to marshal a
file through a POST then bit by bit. Otherwise we just use a base64
binary stream which the SOAP envelope delivers as a byte [ ].

I've never seen this done with a web service. Do you mean that you POST to a
..ASMX file? Could you post a simple example?
 
B

Brybot

I am trying to allow HTTP POST file uploads to my web service.
Currently I have it working perfectly for a SOAP/XML request reading
in a byte[ ] using MemoryStream/FileStream but I cannot figure out how
to encode a file on a POST to the same web service. The definition
requires a base64binary encoded file, which I have tried. The form is
also using a mutlipart/form-data enctype, but I either get a 500 error
or 'Request format is invalid'. Is there a trick to serializing a
form so that the web service will accept it as a byte[ ]?
Alternatively, I would be happy to differentiate the methods used and
create the files accordingly, ie. if its done over SOAP/XML use my
current method, or if its a POST call, use HttpFileCollection or
something? Can you differentiate how a web service was called within
the service itself?
Well it appears that if I convert to binary and separate each bit out
like &param=bit0&param=bit1&param=bit2 etc... it will work...
unfortunately these files are +1Gb. Is there a better way to do this?
XML Web Services are about XML. I don't think you're going to get files
to
work the way you want to.
OTOH, WCF supports streaming data. See Large Data and Streaming
(http://msdn2.microsoft.com/en-us/library/ms733742.aspx), and How to:
Enable
Streaming (http://msdn2.microsoft.com/en-us/library/ms789010.aspx).
Its not the files that are the problems, you can stream the files just
fine through XML, its the method of form POSTing a file to an XML
webservice, which again is possible without changing a thing, but you
have to marshal the file into binary and send it 1 bit to a post
variable. I was just wondering if there is an easier way to marshal a
file through a POST then bit by bit. Otherwise we just use a base64
binary stream which the SOAP envelope delivers as a byte [ ].

I've never seen this done with a web service. Do you mean that you POST to a
.ASMX file? Could you post a simple example?

For sure, if you enable HTTP-POST in your web.config (or
machine.config), your asmx descriptions include POST examples as
well. It'll demonstrate with GET because its easier to see and
essentially the same thing:

http://webservice/MethodName?var1=x&var2=y

that works fine and takes two variables, but for sending files (var3)
via POST or GET you need to do something like this:

http://webservice/MethodName?var1=x&var2=y&var3=1&var3=0&var3=1...&var3=1

you need to send each bit of the file in its own container (var3).
The webservice sees this as your bit [ ] and the file is demarshalled
correctly, but the POST/GET headers become incredibly big.

I've gotten the clients to move onto using SOAP, but I was wondering
for professional curiosity if there was a better way of doing it. If
you're using POST you can always look to httpcontext for uploaded
files, but thats not really using the webservice properly or securely,
probably the only viable solution though.
 
J

John Saunders [MVP]

Brybot said:
On Jul 5, 7:41 pm, "John Saunders [MVP]" <john.saunders at
trizetto.com> wrote:

I am trying to allow HTTP POST file uploads to my web service.
Currently I have it working perfectly for a SOAP/XML request
reading
in a byte[ ] using MemoryStream/FileStream but I cannot figure out
how
to encode a file on a POST to the same web service. The definition
requires a base64binary encoded file, which I have tried. The form
is
also using a mutlipart/form-data enctype, but I either get a 500
error
or 'Request format is invalid'. Is there a trick to serializing a
form so that the web service will accept it as a byte[ ]?
Alternatively, I would be happy to differentiate the methods used
and
create the files accordingly, ie. if its done over SOAP/XML use my
current method, or if its a POST call, use HttpFileCollection or
something? Can you differentiate how a web service was called
within
the service itself?
Well it appears that if I convert to binary and separate each bit
out
like &param=bit0&param=bit1&param=bit2 etc... it will work...
unfortunately these files are +1Gb. Is there a better way to do
this?
XML Web Services are about XML. I don't think you're going to get
files
to
work the way you want to.
OTOH, WCF supports streaming data. See Large Data and Streaming
(http://msdn2.microsoft.com/en-us/library/ms733742.aspx), and How to:
Enable
Streaming (http://msdn2.microsoft.com/en-us/library/ms789010.aspx).
Its not the files that are the problems, you can stream the files just
fine through XML, its the method of form POSTing a file to an XML
webservice, which again is possible without changing a thing, but you
have to marshal the file into binary and send it 1 bit to a post
variable. I was just wondering if there is an easier way to marshal a
file through a POST then bit by bit. Otherwise we just use a base64
binary stream which the SOAP envelope delivers as a byte [ ].

I've never seen this done with a web service. Do you mean that you POST
to a
.ASMX file? Could you post a simple example?

For sure, if you enable HTTP-POST in your web.config (or
machine.config), your asmx descriptions include POST examples as
well. It'll demonstrate with GET because its easier to see and
essentially the same thing:

http://webservice/MethodName?var1=x&var2=y

that works fine and takes two variables, but for sending files (var3)
via POST or GET you need to do something like this:

http://webservice/MethodName?var1=x&var2=y&var3=1&var3=0&var3=1...&var3=1

you need to send each bit of the file in its own container (var3).
The webservice sees this as your bit [ ] and the file is demarshalled
correctly, but the POST/GET headers become incredibly big.

I've gotten the clients to move onto using SOAP, but I was wondering
for professional curiosity if there was a better way of doing it. If
you're using POST you can always look to httpcontext for uploaded
files, but thats not really using the webservice properly or securely,
probably the only viable solution though.

Would this work for you? If not, I'm curious to know why not:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top