title: WCF - Streaming file upload over http
body: <p>I am trying to build a WCF service that will allow my WPF desktop clients to upload files to a server.</p>
  
  <p>I adapted a code sample from The Code Project (<a href="http://www.codeproject.com/KB/WCF/UploadlargeFilesWCFHTTP.aspx" rel="nofollow">WCF Streaming: Upload/Download Files Over HTTP</a>) and I've looked at several SO posts as well, but can't seem to get this working.</p>
  
  <p>When I execute the code, it fails with a null reference exception at the point that the server tries to read the stream that has been passed through the interface.</p>
  
  <p>At this point, I am rather lost and don't know how to fix this up. Any suggestions are appreciated.</p>
  
  <p>Code samples follow:</p>
  
  <p>CustomerDocumentModel is the data element that I pass through the WCF interface with the stream to read the client side file:</p>
  
  <pre><code>[DataContract]
  [KnownType(typeof(System.IO.FileStream))]
  public class CustomerDocumentModel : IDisposable
  {
      public CustomerDocumentModel()
      {
      }
  
      public CustomerDocumentModel(string documentName, string path)
      {
          DocumentName = documentName;
          Path = path;
      }
  
      [DataMember]
      public string DocumentName;
  
      [DataMember]
      public string Path;
  
      [DataMember]
      public System.IO.Stream FileByteStream;
  
      public void Dispose()
      { 
          if (FileByteStream != null)
          {
              FileByteStream.Close();
              FileByteStream = null;
          }
      }
  }
  </code></pre>
  
  <p>IBillingService is the interface definition for my WCF service:</p>
  
  <pre><code>[ServiceContract]
  public interface IBillingService
  {
      // other methods redacted...
  
      [OperationContract]
      void UploadCustomerDocument(CustomerDocumentModel model);
  }
  </code></pre>
  
  <p>The class BillingService implements the WCF service:</p>
  
  <pre><code>[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
  public class BillingService : IBillingService
  {
      // Other methods redacted ...
  
      public void UploadCustomerDocument(CustomerDocumentModel model)
      {
          string path = HttpContext.Current.Server.MapPath(
              String.Format("/Documents/{1}",
                  model.DocumentName));
  
          using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
          {
              const int bufferSize = 4096;
              byte[] buffer = new byte[bufferSize];
  
              int size = 0;
              try
              {
                  // The following Read() fails with a NullReferenceException
                  while ((size = model.FileByteStream.Read(buffer, 0, bufferSize)) &gt; 0)
                  {
                      stream.Write(buffer, 0, size);
                  }
              }
              catch
              {
                  throw;
              }
              finally
              {
              stream.Close();
              model.FileByteStream.Close();
              }
          }
      }
  }
  </code></pre>
  
  <p>A few relevant bits from the web.config on my WCF web server:</p>
  
  <pre><code>&lt;system.web&gt;
      &lt;compilation debug="true" targetFramework="4.0" /&gt;
      &lt;httpRuntime maxRequestLength="2097151" useFullyQualifiedRedirectUrl="true" executionTimeout="360"/&gt;
  &lt;/system.web&gt;
  
  &lt;system.serviceModel&gt;
      &lt;serviceHostingEnvironment
          aspNetCompatibilityEnabled="true"
          multipleSiteBindingsEnabled="true" /&gt;
      &lt;bindings&gt;
          &lt;basicHttpBinding&gt;
              &lt;binding name="userHttps" transferMode="Streamed" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"&gt;
                  &lt;readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /&gt;
                  &lt;security mode="None" /&gt;
              &lt;/binding&gt;
          &lt;/basicHttpBinding&gt;
      &lt;/bindings&gt;
      &lt;behaviors&gt;
          &lt;serviceBehaviors&gt;
              &lt;behavior name=""&gt;
                  &lt;dataContractSerializer maxItemsInObjectGraph="2147483646"/&gt;
                  &lt;serviceDebug includeExceptionDetailInFaults="true" /&gt;
                  &lt;serviceMetadata httpGetEnabled="true" /&gt;
              &lt;/behavior&gt;
          &lt;/serviceBehaviors&gt;
      &lt;/behaviors&gt;
  &lt;/system.serviceModel&gt;
  </code></pre>
  
  <p>The client is a WPF/MVVM app that creates a CustomerDocumentModel model, uses an OpenFileDialog to Open() the file stream and then passes the model to the UploadCustomerDocument method on WCF Service.</p>
  
  <p>If I am missing any relevant details, please ask.</p>