WCF - File Uploading
- I have been trying to create a WCF web service that would allow uploading different files to the web server. There doesn't seem to be much out there with regards to file uploading and WCF but I did manage to find Kjell-Sverre Jerijærvi post and decided to base my first attempt on his article.
That didn't go too well. I have configured a simple HTML upload client and setting the WCF Service to stream a file with Mtom message encoding ended up in failure. Using the MS Service trace tool I was able to find that the web service was dropping the request ( indicating that it was MALFORMED ) and creating a ProtocolException error.
Then I stumbled upon Carlos Figueira post on "receiving arbitrary data" and went ahead and implement the custom binding to accept RAW. This worked, but still got problems.
I can upload a file (png, pdf, txt, whatever), write the stream using FileStream.write() but when I try to open it there are errors. Images and PDF's don't show and txt files always show the multipart/form-data boundaries.
My questions are:
- Why don't examples like Kjells work with binary data (content-type => application/octet-stream)?
- When using Carlos' custom binding, why are the boundaries being added to the file when written to disk? Am I not implementing the file save correctly?
I've seen some examples that use Byte arrays instead of Streams but Microsofts articles seem to suggest that streaming is the way to go.
SaveFile():Code Snippetpublic void SaveFile(string fileName, Stream logFile)
{
if (!uploadDirectory.EndsWith("\\"))
uploadDirectory += "\\";
WebOperationContext ctx = WebOperationContext.Current;
try
{
FileStream fs = null;
/* USE STREAMING */
using (fs = new FileStream(uploadDirectory + fileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
const int bufferLen = 1024; //read stream @ 4K chunks
byte[] buffer = new byte[bufferLen];
int bytesRead = 0;
while ((bytesRead = logFile.Read(buffer, 0, bufferLen)) > 0)
{
fs.Write(buffer, 0, bytesRead);
ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Continue;
}
fs.Close();
logFile.Close();
ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
return;
}
}
catch (IOException ex)
{
throw ex;
}
}
Todas las respuestas
- Here's the sample I've based my solution on.http://www.codeproject.com/KB/WCF/WCF_FileTransfer_Progress.aspxIt would be really nice if the community could get some prescriptive guidance for this common task of uploading and downloading files over HTTP from the Microsoft WCF team.Thanks,Will.
- Thanks for the link.
One question that comes to mind: What binding are you using on your endpoint (e.g. basicHttpBinding) ?
How is your web.config configured?
Thanks
Jose - I've got it working with both wsHTTPBinding and basicHttpBinding. My web.config just adds all the WCF stuff and increases the maxReqeustLength like so:<system.web>
<httpRuntime maxRequestLength="8000" - This is what I don't understand and maybe has to do with .NETfx 3.5 SP1 or something but I implemented your code in a simple service and I still get (in the tracer log)Content Type multipart/form-data; boundary=---------------------------13707388261950367213631361083 was sent to a service expecting multipart/related; type="application/xop+xml". The client and service bindings may be mismatched.I know that the html upload form that I created sends with enctype = multipart/form-data and that it also goes up with a content type of application/octet-stream. Apparently this is causing a problem with the service.Has anyone had this issue before?I don't have this problem with Carlos' "raw data" code, but I still can't get the files to open correctly once on the server.
- Propuesto como respuestaRodolfo Barriga jueves, 19 de noviembre de 2009 14:38
- How are you hosting your servce ? IIS6, IIS7 integrated or classic mode, WAS, self, console, or just the VS built-in web server ?
- The service is hosted on IIS 5.1 (Win XP Pro)

