How to Download a Large File from a WCF Service?

By | March 12, 2014

While reading WCF technical forums, I have come across the followingquestionsanumber of times.

  • How to download a large file from a WCF Service?
  • I am getting error while transferring a large file from WCF service to client?
  • How to send large messages or data from WCF Service to a client?

So, I decided to write a simple WCF Tutorial on this topic with possible approaches to answer the above questions. I’ll follow a step by step method to provide a complete solution as follows:
So, we will try to understand the problem that is involved with downloading a large file from a WCF service. For the purpose of implementation, we will create a simple WCF Service that returns a byte array.

1. First of all, lets create a WCF service contract IMyBookService that returns a Book.

public interface IMyBookService
{
   [OperationContract]
   Book DownloadBook();
}

Book Data Contract has multiple members i.e. Title, ISBN, Author and Data (a byte array).

[DataContract]
public class Book
{
        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public string ISBN { get; set; }

        [DataMember]
        public string Author { get; set; }

        [DataMember]
        public byte[] Data { get; set; }
}

2. Implementation of IMyBookService is as follows:

public class MyBookService : IMyBookService
    {
        Book IMyBookService.DownloadBook()
        {
            Book myBook = new Book();
            myBook.Title = “WCF RESTful Service”;
            myBook.ISBN = “178-3-15-146510-0”;
            myBook.Author = “Imran Abdul Ghani”;
            myBook.Data = File.ReadAllBytes(@”D:MyBooksWCF RESTful Service.doc”); 

            return myBook;
        }
    }

3.Configuration settings for the service is given below:

<services>
   <service name=”BookService.MyBookService” behaviorConfiguration=”serviceBehavior”>
<endpoint address=””MyBookService”
                             Binding = “wsHttpBinding” bindingConfiguration = “wsBindingConfig”
 Contract = “BookService.IMyBookService” />
<host>
baseAddress=”http://localhost:9999″ />
</host>
   </service>
</services>
<bindings>
<wsHttpBinding>
<binding name=”wsBindingConfig” messageEncoding=”Text” />
</wsHttpBinding>
</bindings>

In order to consume the service the client side code will be as follows:

BookService.MyBookServiceClient client = new BookService.MyBookServiceClient();
client.Book myBook = client.DownloadBook();
File.WriteAllBytes(@”D:MyDownloadedBooks” + myBook.Title, myBook.Data);

When we call the Download method of MyBookService through client code, it will generate the following exception:

“Maximum message size quota for incoming messages (65536) has been exceeded….”

So, we have reached at a point that how a WCF service behaves by default for such scenarios. One thing is obvious from above error message that Maximum message size for downloading a file in WCF, by default, is around 65K. In order to handle this issue is simply increase the value of two configuration settings:

  • maxReceivedMessageSize
  • readerQuotas

So,  updated bindingConfiguration will be as follows:

<bindings>
<wsHttpBinding>
<binding name=”wsBindingConfig”
                                       maxReceivedMessageSize=”10000000″
                                       messageEncoding=”Text”>
<readerQuotas maxArrayLength=”1000000″ />
</binding>
</wsHttpBinding>
</bindings>

Now, if we run the above code, it will work fine and file will be successfully downloaded. Cheers…

Although, we got the answer to questions asked at the start of this WCF Service tutorial but this approach has some disadvantages with respect to performance.

  • As we have seen, that we are using default messageEncoding i.e. “Text”. Text encoding uses base 64 encoding format. Base 64 encoded files are normally larger than original file size, so further increasing the file size to approximately 30% unnecessarily.
  • Also there is a cost for encoding at one end and decoding on the other.

In order to do the same, we have a better approach and that is to use MTOM (Message Transmission Optimization Mechanism) message encoding. We just need to replace MTOM in above binding configuration instead of Text.

<bindings>
<wsHttpBinding>
<binding name=”wsBindingConfig”
                                      maxReceivedMessageSize=”10000000″
                                      messageEncoding=”Mtom”>
<readerQuotas maxArrayLength=”1000000″ />
</binding>
</wsHttpBinding>
</bindings>

Using MTOM message encoding format has advantages:

  • It keeps the size of message under control.
  • Interopable because its based on Open specification.
Hopefully, this simple WCF article will be helpful in answering the above mentioned questions. Further, I am planning to write another Tutorial on “How to upload large data to a WCF Service?” later this month. So, be in touch and enjoy service programming.

Top 10 Interview Questions and Answers Series:

Category: Uncategorized Tags: ,

About IMRAN ABDUL GHANI

Imran Abdul Ghani is working as Software Developer(Senior) with extensive knowledge in Web development technologies especially C#, ASP.NET, MVC, WCF, Web API, ADO.NET Entity Framework, jQuery etc. He has several years of experience in designing/developing enterprise level applications. He is Microsoft Certified Solution Developer for .NET (MCSD.NET) since 2005. You can reach his blogging at www.webdevelopmenthelp.net, www.topwcftutorials.net, and www.sharepointfordummies.net.