Click here to Skip to main content
15,881,204 members
Articles / Programming Languages / C#
Technical Blog

How to Download a Large File from a WCF Service?

Rate me:
Please Sign up or sign in to vote.
3.58/5 (8 votes)
12 Mar 2014CPOL3 min read 24.4K   9   6
How to download a large file from a WCF service

While reading WCF technical forums, I have come across the following questions a number of times:

  • How to download a large file from a WCF Service?
  • I am getting an 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, let's create a WCF service contract IMyBookService that returns a Book.
    C#
    public interface IMyBookService
    {
       [OperationContract]
       Book DownloadBook();
    }

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

    C#
    [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:
    C#
    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:\MyBooks\WCF RESTful Service.doc"); 
    
                return myBook;
            }
        }
  3. Configuration settings for the service is given below:
    XML
    <services>
       <service name="BookService.MyBookService" behaviorConfiguration="serviceBehavior">
                <endpoint address=""MyBookService"
                                 Binding = "wsHttpBinding" bindingConfiguration = "wsBindingConfig"
                                 Contract = "BookService.IMyBookService" />
                 <host>
                          <add 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:

C#
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 the above error message that Maximum message size for downloading a file in WCF, by default, is around 65K. In order to handle this issue, simply increase the value of two configuration settings:

  • maxReceivedMessageSize
  • readerQuotas

So, updated bindingConfiguration will be as follows:

XML
<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 the file will be successfully downloaded. Cheers...

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

  • As we have seen, we are using default messageEncoding i.e. "Text". Text encoding uses base 64 encoding format. Base 64 encoded files are normally larger than the 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 the above binding configuration instead of Text.

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

Using MTOM message encoding format has advantages listed below:

  • It keeps the size of message under control.
  • Interoperable because it's 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.

Reader of this article might also be interested in:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Emaratech
United Arab Emirates United Arab Emirates
Imran Abdul Ghani has more than 10 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 WCF Tutorials, Web Development, SharePoint for Dummies.

Comments and Discussions

 
PraiseExcellent work Pin
sardaratta2-Nov-15 20:40
sardaratta2-Nov-15 20:40 
GeneralClass Book Pin
arif200621-Nov-14 4:48
arif200621-Nov-14 4:48 
BookService.MyBookServiceClient client = new BookService.MyBookServiceClient();
client.Book myBook = client.DownloadBook();Over here it should be client.book or BookService.Book

Please let me know.....

GeneralMy vote of 1 Pin
Gwynge26-Jun-14 21:14
Gwynge26-Jun-14 21:14 
QuestionmaxReceivedMessageSize is a int type Pin
comiscience13-Mar-14 22:03
comiscience13-Mar-14 22:03 
AnswerRe: maxReceivedMessageSize is a int type Pin
Imran Abdul Ghani14-Mar-14 5:12
Imran Abdul Ghani14-Mar-14 5:12 
GeneralRe: maxReceivedMessageSize is a int type Pin
comiscience14-Mar-14 22:53
comiscience14-Mar-14 22:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.