0

I am creating a WCF REST webservice that will be used to download large files (potentially more than 2GB). The files are csv files that are not stored on a hard drive, instead they are formed in runtime when the request is made. Because of that I chose to write csv file directly into HttpResponse avoiding any intermediate containers that will not hold more than 2GB of data. This is a test code I wrote that does what I've described:

[ServiceContract]
public interface IDownloadService
{
    [OperationContract]
    [WebInvoke(
        Method = "GET",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "")]
    void Download();
}

public class DownloadService : IDownloadService
{
    public void Download()
    {
        var response = HttpContext.Current.Response;
        response.Clear();
        response.ContentType = "application/csv";
        response.AddHeader("Content-Disposition", "attachment; filename=myfile.csv");

        //This is a small test csv file, it will be replaced with a big file,
        //that will be formed in runtime and written piece by piece into Response.OutputStream
        response.BinaryWrite(System.Text.Encoding.UTF8.GetBytes("1,2,3"));
        response.Flush();
        response.Close();
        response.End();
    }
}

This is my Web.config, just in case:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="RestWcf.DownloadService">
        <endpoint address="" binding="webHttpBinding" behaviorConfiguration="web" contract="RestWcf.IDownloadService"/>
      </service>
    </services>   
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

Now here's the interesting part when I call this webservice method from Google Chrome, first it starts downloading the file and at the end of the downloading Chrome gives me the error Failed - Network error, when I try to call it from Postman I get Could not get any response message with no response generated, finally when I try to call it from Fiddler I get 504 response with more informative message ReadResponse() failed: The server did not return a complete response for this request. Server returned 384 bytes.

Any ideas on what's going on here and how can I fix this weird behavior?

Mykhailo Seniutovych
  • 3,527
  • 4
  • 28
  • 50
  • Are the bindingConfiguration attributes properly set so as to return the size of the data you are dealing with? –  May 07 '18 at 14:06
  • @binDebug I did not configure this attribute since as far as I know they're used when the method returns something, in my case I'm writing directly to HttpResponse. Anyway in the test code I provided, the file is small and it still doesn't work. I've also included the web.config if that helps. – Mykhailo Seniutovych May 07 '18 at 14:20
  • So maybe configuring the httpRuntime setting might help? https://msdn.microsoft.com/en-us/library/e1f13641(v=vs.100).aspx –  May 07 '18 at 14:28

0 Answers0