Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Part 35 - Sending large messages in WCF using MTOM

Suggested Videos
Part 32 - Message Exchange Patterns in WCF
Part 33 - OneWay Message Exchange Pattern in WCF
Part 34 - Duplex message exchange pattern in WCF



In this video we will discuss, sending large binary messages in WCF using MTOM for better performance.

The default message encoding mechanism in WCF is Text, which base64 encodes data. This has the following 2 disadvantages
1. Base64 encoding bloats the message size by approximately 33%.
2. Involves additional processing overhead to base64 encode and decode.



The preferred approach to send large binary messages in WCF is to use MTOM message encoding. MTOM is an interoperable standard and stands for Message Transmission Optimization Mechanism. MTOM does not base64 encode data. This also means, the additional processing overhead to base64 encode and decode data is removed. Hence, MTOM can significantly improve the overall message transfer performance. 

With Text Message encoding, the binary data is base64 encoded and it is embedded in the SOAP envelop. With MTOM, binary data is included as a MIME (Multipurpose Internet Mail Extensions) attachment.

Example: 
Step 1: Create a class library project with name = DownloadService. Delete the autogenerated class1.cs file and app.config file.

Step 2: Right click on DownloadService solution in solution explorer and add a WCF service with name = DownloadService.

Step 3: Copy and paste the following code in IDownloadService.cs file
using System.Runtime.Serialization;
using System.ServiceModel;

namespace DownloadService
{
    [ServiceContract]
    public interface IDownloadService
    {
        [OperationContract]
        File DownloadDocument();
    }

    [DataContract]
    public class File
    {
        [DataMember]
        public string Name { get; set; }

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

}

Step 4: Copy and paste the following code in DownloadService.cs file
namespace DownloadService
{
    public class DownloadService : IDownloadService
    {
        public File DownloadDocument()
        {
            File file = new File();
            file.Content = System.IO.File.
                ReadAllBytes(@"C:\Data\Introduction to WCF.ppt");
            file.Name = "Introduction to WCF.ppt";

            return file;
        }
    }

}

Step 5: Host the DownloadService in IIS. We discussed hosting WCF service in IIS in Part 29 of the WCF tutorial. Use the following configuration. Notice that at the moment we are using Text message encoding.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttp" messageEncoding="Text">
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mexBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="mexBehavior"
               name="DownloadService.DownloadService">
        <endpoint address="DownloadService" binding="wsHttpBinding"
                  bindingConfiguration="wsHttp"
                  contract="DownloadService.IDownloadService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>

</configuration>

Step 6: Create a Windows application with name = Client. Drag and drop a button control on the windows form. Double click the button control to generate the click event handler. Add a service reference to the DownloadService. Copy and paste the following code.
private void button1_Click(object sender, EventArgs e)
{
    DownloadService.DownloadServiceClient client =
        new DownloadService.DownloadServiceClient();
    DownloadService.File file = client.DownloadDocument();
    System.IO.File.WriteAllBytes
        (@"C:\DownloadedFiles\" + file.Name, file.Content);
    MessageBox.Show(file.Name + " downloaded");

}

Step 7: Run the client application and click the Download File button. We get the following error.
The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.

To fix this specify maxReceivedMessageSize and maxArrayLength both in the WCF service and the client.
<bindings>
  <wsHttpBinding>
    <binding name="wsHttp" messageEncoding="Text"
              maxReceivedMessageSize="700000">
      <readerQuotas maxArrayLength="700000"/>
    </binding>
  </wsHttpBinding>

</bindings>

Step 8: Open Fiddler tool and notice the data that is exchanged between the client and the WCF service.
Content Type is application / soap + xml
The large binary message is base64 encoded and is part of SOAP envelope
Text message encoding in wcf

Click on Statistics tab and notice bytes received
Sending large messages in wcf

Step 9: Now set messageEncoding="Mtom" in both the WCF service and the client
<bindings>
  <wsHttpBinding>
    <binding name="wsHttp" messageEncoding="Mtom"
             maxReceivedMessageSize="700000">
      <readerQuotas maxArrayLength="700000"/>
    </binding>
  </wsHttpBinding>

</bindings>

Step 10: Run the client application and click Download File button. In fiddler, notice the data that is exchanged between the client and the WCF service.
Mtom message encoding in wcf

Content Type is multipart/related
The large binary message is not base64 encoded and included as a MIME attachment

Click on Statistics tab and notice bytes received
Sending large messages in wcf with mtom

The bytes received with MTOM is significantly less, when compared with Text message encoding.

wcf tutorial

3 comments:

  1. Hi Venkat,

    I'm following your tutorial but I'm stuck with the IIS thing. It doesn't allow me to browse when after creating the application site. I'm using IIS 7.5. Any ideas?

    Thank you!

    ReplyDelete
  2. When change to Mtom occurs an error :

    NetdispatcherFaultException


    The formatter threw an exception while trying to deserialize the message: Error while trying to deserialize the http://tempuri.org/:DownloadDocumentResult parameter. The InnerException message was' Error deserializing the object of type WindowsClient.DownloadService.File. Share maximum length of the array (16384) to read the XML data is exceeded. You can increase this fee


    VS 2012

    ReplyDelete

It would be great if you can help share these free resources