How to: Enable a Web Service to Send and Receive Large Amounts of Data

WSE 3.0 supports the Message Transmission Optimization Mechanism (MTOM) specification for transmitting large amounts of data to and from Web services.

To enable a Web service to send and receive large amounts of data

  1. Open the Web service project in Visual Studio 2005.

  2. Enable the project to use WSE and for it to use the WSE SOAP protocol factory.

    1. In Solution Explorer, right-click the project name, and then click WSE Settings 3.0….
    2. Select the General tab.
    3. Select Enable this project for Web Services Enhancements and Enable Microsoft Web Services Enhancements SOAP Protocol Factory.
  3. Specify that the Web service can accept SOAP messages encoded using MTOM.

    1. In Solution Explorer, right-click the project name, and then click WSE Settings 3.0….
    2. Select the Messaging tab.
    3. Choose optional or always for the Server Mode.
      The optional MTOM Mode specifies that WSE processes incoming SOAP messages whether or not they are MTOM encoded and that all SOAP responses and SOAP faults are MTOM encoded.
      The always MTOM Mode specifies that all incoming and outgoing SOAP messages must be MTOM encoded. When a SOAP request is received that is not encoded using MTOM, a SOAP fault is returned to the sender.
    4. Click OK to dismiss the dialog.
      This adds an <mtom> Element to the Web service's Web.config file.
  4. Add a Web service method that has a parameter or return value with a type that is either a byte array or a type that contains a byte array.

    The following code example defines a Web service method that returns a byte array.

    <WebMethod()> _
    Public Function GetFile(ByVal filename As String) As Byte()
    
    [WebMethod]
    public byte[] GetFile(string fileName)
    
  5. When the return value contains a byte array, populate the byte array.

    The following code example is a Web service method that populates a byte array using the contents from a file on disk and then returns it in the SOAP message.

    <WebMethod()> _
    Public Function GetFile(ByVal filename As String) As Byte()
        Dim response As Byte()
        Dim filePath As String = AppDomain.CurrentDomain.BaseDirectory + "App_Data\" + filename
        response = File.ReadAllBytes(filePath)
        Return response
    End Function
    
    [WebMethod]
    public byte[] GetFile(string fileName)
    {
    
        byte[] response;
        String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName;
        response = File.ReadAllBytes(filePath);
        return response;
    }
    
  6. When the amount of data send or received by the Web service exceeds 4 MB, configure the Web server to handle the larger amount of data.

    1. Increase the ASP.NET limits on the maximum size of SOAP messages and the maximum number of seconds that a request is allowed to execute by adding the <httpRuntime> configuration element to the application's web.config file.
      The following code example sets the ASP.NET limit on the maximum size of an incoming request to 400MB and the maximum amount of time a request is allowed to execute to 5 minutes (300 seconds).

      <configuration>
        <system.web>
        <httpRuntime maxMessageLength="409600"
          executionTimeoutInSeconds="300"/>
        </system.web>
      </configuration>
      
    2. Increase the WSE limit on the maximum size of SOAP messages using the <maxMessageLength> Element.
      To send and receive the largest possible SOAP messages, set the value of the <maxMessageLength> element to -1.
      The following code example disables the limit on the maximum size of SOAP messages by WSE.

      <configuration>
        <microsoft.web.services3>
          <messaging>
            <maxMessageLength value="-1" />
          </messaging>
        </microsoft.web.services3>
      </configuration>
      

Example

The following code example requires all incoming and outgoing SOAP messages to be MTOM encoded.

<configuration>
  <configSections>
    <section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <system.web>
    <webServices>
      <soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </webServices>
  </system.web>
  <microsoft.web.services3>
    <messaging>
      <mtom serverMode="always" />
    </messaging>
  </microsoft.web.services3>
</configuration>

The following code example demonstrates how to define a Web service method that can be MTOM encoded. The example contains two Web service methods, GetFile and GetFileClass, that return a byte array and a class that contains a byte array, respectively. The SOAP message including the binary data is secured using the ServerPolicy policy.

Imports System.CodeDom.Compiler
Imports System.Reflection
Imports System.IO
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols

Imports System.Xml
Imports System.Xml.Schema
Imports System.Xml.Serialization

Imports Microsoft.Web.Services3
Imports Microsoft.Web.Services3.Design


<Policy("ServerPolicy")> _
<WebService(Namespace:="http://stockservice.contoso.com/wse/samples/2005/10")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
Public Class BinaryDataMTOMService
    Inherits System.Web.Services.WebService

    Public Sub BinaryDataMTOMService()

    End Sub
    
    'This Web service method returns a class that contains a byte array.
    <WebMethod()> _
    Public Function GetFile(ByVal filename As String) As Byte()
        Dim response As Byte()
        Dim filePath As String = AppDomain.CurrentDomain.BaseDirectory + "App_Data\" + filename
        response = File.ReadAllBytes(filePath)
        Return response
    End Function
    
    'This Web service method returns a class that contains a byte array.
    <WebMethod()> _
    Public Function GetFileWithClass(ByVal fileName As String) As GetFileResponse
        Dim response As New GetFileResponse()
        response.FileName = Path.GetFileName(fileName)
        Dim filePath As String = AppDomain.CurrentDomain.BaseDirectory + "App_Data\" + fileName
        response.FileContents = File.ReadAllBytes(filePath)
        Return response
    End Function
    
    ' This is the type that is returned by the GetFileWithClass Web service method.
    <XmlRoot("getFileResponse", [Namespace]:="http://stockservice.contoso.com/wse/samples/2005/10")> _
    Public Class GetFileResponse
        <XmlElement("fileName", IsNullable:=False)> _
        Public FileName As String

        <XmlElement("fileData", IsNullable:=False)> _
        Public FileContents() As Byte
    End Class 'GetFileResponse

End Class
using System;
using System.Collections;
using System.ComponentModel;
using System.CodeDom.Compiler;
using System.Data;
using System.Reflection;
using System.Diagnostics;

using System.IO;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Design;

[WebService(Namespace = "http://stockservice.contoso.com/wse/samples/2005/10")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Policy("ServerPolicy")]
public class BinaryDataMTOMService : System.Web.Services.WebService
{
    public BinaryDataMTOMService()
    {
    }
    // This Web service method returns a byte array.
    [WebMethod]
    public byte[] GetFile(string fileName)
    {

        byte[] response;
        String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName;
        response = File.ReadAllBytes(filePath);
        return response;
    }

    // This Web service method returns a class that contains a byte array.
    [WebMethod]
    public GetFileResponse GetFileClass(string fileName)
    {
        GetFileResponse response = new GetFileResponse();
        response.FileName = Path.GetFileName(fileName);
        String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName;
        response.FileContents = File.ReadAllBytes(filePath);  
        return response;
    }
    // This is the type that is returned by the GetFileWithClass Web service method.
    [XmlRoot("getFileResponse", Namespace = "http://stockservice.contoso.com/wse/samples/2005/10")]
    public class GetFileResponse
    {
        [XmlElement("fileName", IsNullable = false)]
        public string FileName;

        [XmlElement("fileData", IsNullable = false)]
        public byte[] FileContents;
    }
}

See Also

Tasks

How to: Send and Receive Large Amounts of Data to and from a Web Service

Reference

<mtom> Element