WCF - File Uploading<font size=2><span style="font-family:Arial">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 </span></font><span class="post-author vcard"><span class=fn>Kjell-Sverre Jerijærvi post and decided to base my first attempt on his article.<br><br>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. <br><br>Then I stumbled upon Carlos Fig</span></span>ueira post on &quot;receiving arbitrary data&quot; and went ahead and implement the custom binding to accept RAW. This worked, but still got problems.<br><br>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.<br><br>My questions are:<br><br> - Why don't examples like Kjells work with binary data (content-type =&gt; application/octet-stream)?<br> - 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?<br><br>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.<br><br> <div style="text-align:left"> SaveFile(): <div class=codeseg> <div class=codecontent> <div class=codesniptitle><span style="width:100%">Code Snippet</span></div> <p>       public void SaveFile(string fileName, Stream logFile)<br>        {<br>            if (!uploadDirectory.EndsWith(&quot;\\&quot;))<br>                uploadDirectory += &quot;\\&quot;;<br><br>            WebOperationContext ctx = WebOperationContext.Current;<br><br><br>            try<br>            {<br>                FileStream fs = null;<br>                /* USE STREAMING */<br><br>                using (fs = new FileStream(uploadDirectory + fileName, FileMode.Create, FileAccess.Write, FileShare.None))<br>                {<br>                    const int bufferLen = 1024; //read stream @ 4K chunks<br>                    byte[] buffer = new byte[bufferLen];<br><br>                    int bytesRead = 0;<br>                    while ((bytesRead = logFile.Read(buffer, 0, bufferLen)) &gt; 0)<br>                    {<br>                        fs.Write(buffer, 0, bytesRead);<br>                        ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Continue;<br>                    }<br><br>                    fs.Close();<br>                    logFile.Close();<br><br>                    ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;<br>                    return;<br>                }<br>            }<br>            catch (IOException ex)<br>            {<br>                throw ex;<br>            }<br>        }</p></div></div><br></div>© 2009 Microsoft Corporation. All rights reserved.Thu, 19 Nov 2009 14:45:31 Z79e2b543-177a-4a63-b5f5-d5bb189f749dhttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#79e2b543-177a-4a63-b5f5-d5bb189f749dhttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#79e2b543-177a-4a63-b5f5-d5bb189f749djd12215http://social.msdn.microsoft.com/Profile/en-US/?user=jd12215WCF - File Uploading<font size=2><span style="font-family:Arial">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 </span></font><span class="post-author vcard"><span class=fn>Kjell-Sverre Jerijærvi post and decided to base my first attempt on his article.<br><br>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. <br><br>Then I stumbled upon Carlos Fig</span></span>ueira post on &quot;receiving arbitrary data&quot; and went ahead and implement the custom binding to accept RAW. This worked, but still got problems.<br><br>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.<br><br>My questions are:<br><br> - Why don't examples like Kjells work with binary data (content-type =&gt; application/octet-stream)?<br> - 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?<br><br>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.<br><br> <div style="text-align:left"> SaveFile(): <div class=codeseg> <div class=codecontent> <div class=codesniptitle><span style="width:100%">Code Snippet</span></div> <p>       public void SaveFile(string fileName, Stream logFile)<br>        {<br>            if (!uploadDirectory.EndsWith(&quot;\\&quot;))<br>                uploadDirectory += &quot;\\&quot;;<br><br>            WebOperationContext ctx = WebOperationContext.Current;<br><br><br>            try<br>            {<br>                FileStream fs = null;<br>                /* USE STREAMING */<br><br>                using (fs = new FileStream(uploadDirectory + fileName, FileMode.Create, FileAccess.Write, FileShare.None))<br>                {<br>                    const int bufferLen = 1024; //read stream @ 4K chunks<br>                    byte[] buffer = new byte[bufferLen];<br><br>                    int bytesRead = 0;<br>                    while ((bytesRead = logFile.Read(buffer, 0, bufferLen)) &gt; 0)<br>                    {<br>                        fs.Write(buffer, 0, bytesRead);<br>                        ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Continue;<br>                    }<br><br>                    fs.Close();<br>                    logFile.Close();<br><br>                    ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;<br>                    return;<br>                }<br>            }<br>            catch (IOException ex)<br>            {<br>                throw ex;<br>            }<br>        }</p></div></div><br></div>Thu, 11 Sep 2008 07:39:37 Z2008-09-11T07:39:37Zhttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#d4f43f06-e3ba-4d68-84c9-a79344d7ffc2http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#d4f43f06-e3ba-4d68-84c9-a79344d7ffc2Will.Rogershttp://social.msdn.microsoft.com/Profile/en-US/?user=Will.RogersWCF - File Uploading<div><span class=Apple-style-span style="white-space:normal">Here's the sample I've based my solution on.</span></div> <div><span class=Apple-style-span style="white-space:normal"><br></span></div><a title="http://www.codeproject.com/KB/WCF/WCF_FileTransfer_Progress.aspx" href="http://www.codeproject.com/KB/WCF/WCF_FileTransfer_Progress.aspx">http://www.codeproject.com/KB/WCF/WCF_FileTransfer_Progress.aspx</a><font face=Arial size=2></font> <div><span class=Apple-style-span style="white-space:normal"><br></span></div> <div><span class=Apple-style-span style="white-space:normal">It 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.</span></div> <div><span class=Apple-style-span style="white-space:normal"><br></span></div> <div><span class=Apple-style-span style="white-space:normal">Thanks,</span></div> <div><span class=Apple-style-span style="white-space:normal">Will.</span></div>Thu, 11 Sep 2008 11:44:16 Z2008-09-11T11:44:16Zhttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#a5131470-4a5e-4717-93c3-3a176c2e3861http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#a5131470-4a5e-4717-93c3-3a176c2e3861jd12215http://social.msdn.microsoft.com/Profile/en-US/?user=jd12215WCF - File Uploading<font size=2><span style="font-family:Arial">Thanks for the link. <br><br>One question that comes to mind: What binding are you using on your endpoint (e.g. basicHttpBinding) ? <br><br>How is your web.config configured?<br><br>Thanks<br>Jose<br></span></font>Thu, 11 Sep 2008 22:48:04 Z2008-09-11T22:48:04Zhttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#97c3ff8a-e9e6-487e-bf2f-c61e67891dd4http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#97c3ff8a-e9e6-487e-bf2f-c61e67891dd4Will.Rogershttp://social.msdn.microsoft.com/Profile/en-US/?user=Will.RogersWCF - File UploadingI've got it working with both wsHTTPBinding and basicHttpBinding. My web.config just adds all the WCF stuff and increases the maxReqeustLength like so:<font face=Arial size=2></font> <div><span class=Apple-style-span style="white-space:normal"><br></span></div> <div><span class=Apple-style-span style="white-space:normal"><span class=Apple-style-span style="font-size:15px;line-height:20px"><span class=Apple-style-span style="font-family:Courier"><span class=Apple-style-span style="font-size:small">&lt;system.web&gt;<br style="clear:left">&lt;httpRuntime maxRequestLength=&quot;8000&quot;</span></span><br style="clear:left"></span></span></div>Fri, 12 Sep 2008 01:32:35 Z2008-09-12T01:32:35Zhttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#536b772f-5d27-409f-a1d6-3b19a77c6576http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#536b772f-5d27-409f-a1d6-3b19a77c6576jd12215http://social.msdn.microsoft.com/Profile/en-US/?user=jd12215WCF - File UploadingThis 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)<font face=Arial size=2></font> <div><span class=Apple-style-span style="white-space:normal"><br></span></div> <div><span class=Apple-style-span style="white-space:normal"><span class=Apple-style-span style="background-color:rgb(255,255,255)"><span class=Apple-style-span style="color:rgb(255,0,0)">Content Type <span class=Apple-style-span style="font-weight:bold">multipart/form-data</span>; boundary=---------------------------13707388261950367213631361083 was sent to a service expecting multipart/related; type=&quot;<span class=Apple-style-span style="font-weight:bold">application/xop+xml</span>&quot;.  The client and service bindings may be mismatched.</span></span><br></span></div> <div><span class=Apple-style-span style="color:rgb(255,0,0);white-space:normal"><br></span></div> <div><span class=Apple-style-span style="white-space:normal">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.</span></div> <div><span class=Apple-style-span style="white-space:normal"><br></span></div> <div><span class=Apple-style-span style="white-space:normal">Has anyone had this issue before?</span></div> <div><span class=Apple-style-span style="white-space:normal"><br></span></div> <div><span class=Apple-style-span style="white-space:normal">I don't have this problem with Carlos' &quot;raw data&quot; code, but I still can't get the files to open correctly once on the server.</span></div>Fri, 12 Sep 2008 06:19:26 Z2008-09-12T06:19:26Zhttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#097e7fa0-2dbe-4565-87ef-cd4a9469feb9http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#097e7fa0-2dbe-4565-87ef-cd4a9469feb9KjellSJhttp://social.msdn.microsoft.com/Profile/en-US/?user=KjellSJWCF - File UploadingHow are you hosting your servce ? IIS6, IIS7 integrated or classic mode, WAS, self, console, or just the VS built-in web server ? <p align=left><font face=Arial size=2></font> </p>Mon, 22 Sep 2008 19:11:07 Z2008-09-22T19:11:07Zhttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#3ed7de90-e847-47d6-8f2b-76e7ae04213chttp://social.msdn.microsoft.com/Forums/en-US/wcf/thread/79e2b543-177a-4a63-b5f5-d5bb189f749d#3ed7de90-e847-47d6-8f2b-76e7ae04213cjd12215http://social.msdn.microsoft.com/Profile/en-US/?user=jd12215WCF - File Uploading<font size=2><span style="font-family:Arial">The service is hosted on IIS 5.1 (Win XP Pro)<br></span></font>Mon, 22 Sep 2008 19:15:39 Z2008-09-22T19:15:39Z