wcf | dotnet

Download file using WCF REST Service

Download file using WCF Service

Abhith Rajan
Abhith RajanMarch 07, 2018 · 2 min read · Last Updated:

Recently, We deployed a web application in a load balanced environment. And one of the features in the app was to download some data as excel and it was working fine in DEV (as usual) but keep failing in the PROD. When I checked it on the individual servers, all worked fine but not under SLB (Software Load Balancing).

So I reviewed the code and found out that there are two requests being sent, one after another, one for generating the file in the server and another one for fetching the generated file. Pretty bad implementation, right? When is under load balanced environment, the first request may be served from one server and the second from another server. And there was no shared storage space (we used OSS). No sticky session either. So file generated in one server and it is being requested in another server which leads to 404.

To solve, We had to combine both, i.e generate the file and serve it on the same request. To do that, our code look like this,

Service Contract Interface

[WebGet(UriTemplate = "{cultureName}/download/{someId}")]
[OperationContract]
Stream GetReportByDate(string cultureName, string someId);

Of course it is a HTTP GET method. And the implementation looks like below,

public Stream GetReportByDate(string cultureName, string someId)
{
    try
    {
        ...
         // Generate file the usual way
        var filePath = SomeWayGenerateFileAndReturnFilePath();
        if (WebOperationContext.Current != null)
        {
            WebOperationContext.Current.OutgoingResponse.Headers["Content-Disposition"] =
        "attachment; filename=" + fileNameWithExtension;
             WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream";
        }
        return File.OpenRead(filePath);
    }
    catch (Exception exception)
    {
        throw new WebProtocolException(HttpStatusCode.InternalServerError, $"ERROR: Operation faild. {exception.Message}", exception.InnerException);
    }
}

Here ContentType can be whatever it is, if you know it. application/octet-stream is appropriate for entitites whose sole intended purpose is to be saved to disk. If you only generates say PDF, then the content type part can be changed to,

WebOperationContext.Current.OutgoingResponse.Headers["Content-Disposition"]
  = "attachment; filename=MyFileName.pdf";
WebOperationContext.Current.OutgoingResponse.ContentType
  = "application/pdf";

That’s it.

This page is open source. Noticed a typo? Or something unclear?
Improve this page on GitHub


Abhith Rajan

Written byAbhith Rajan
Abhith Rajan is a software engineer by day and a full-stack developer by night. He's coding for almost a decade now. He codes 🧑‍💻, write ✍️, learn 📖 and advocate 👍.
Connect

Is this page helpful?

Related ArticlesView All

Related VideosView All

NativeAOT for .NET APIs Is Here and It’s INSANE!

When to use - IEnumerable vs IList vs ICollection?

What are record types in C# and how they ACTUALLY work

Related Tools & ServicesView All

dotnet.microsoft.com

Try .NET | Runnable .NET code on your site

Try .NET is a service that allows you to embed runnable .NET code snippets into your website, blog, or documentation. Go beyond copy and paste samples to live snippets.