How to: Add Attachments to a SOAP Message by Using DIME

The Web Services Enhancements for Microsoft .NET (WSE) supports attaching files to SOAP messages outside the SOAP envelope; these files are not serialized as XML. This can be beneficial when sending large text or binary files because XML serialization is a very costly process and can result in files much larger than the originals. Direct Internet Message Encapsulation (DIME) is a lightweight, binary message format that WSE uses to encapsulate SOAP messages and their attachments in a DIME message. The following procedure details how to:

  • Create a Web service that can read an image file and return a DIME message that contains a SOAP message and the image file.
  • Create a Windows Forms client that can consume the DIME message created by the Web service and display the image.

To create a Web service that can generate DIME messages containing image attachments

  1. In Visual Studio .NET 2003, create an ASP.NET Web Service project.

    1. On the File menu, select New, and then click Project.
    2. In the Project Types pane, select Visual C# Projects.
    3. In the Templates pane, select ASP.NET Web Service.
    4. In the Location box, enter the Web server name with the project name: https://localhost/DimeGen.
    5. Click OK.
      The DimeGen project is added to the solution. The Component Designer appears in the development environment.
    6. In Solution Explorer, double-click Service1.asmx.
    7. In the Properties window, change the Name property from Service1 to MyDimeService: right-click Service1.asmx, click Rename, and then change the name to MyDimeService.asmx.
  2. Add references to the Microsoft.Web.Services2 and System.Web.Services assemblies.

    1. In Solution Explorer, right-click References, and then select Add Reference.
    2. On the .NET tab, select Microsoft.Web.Services2.dll, and then click Select.
    3. On the .NET tab, select System.Web.Services.dll, and then click Select.
    4. Click OK.
  3. Edit the Web.config file to add WSE functionality to the Web service.

    1. In Solution Explorer, double-click Web.config.

    2. Add the following elements to the Web.config file.
      The type attribute of the <add> Element for <soapExtensionTypes> (WSE for Microsoft .NET) element must not contain line breaks, even though the following sample shows it split across multiple lines for readability.

      <!--This element adds WSE functionality to the Web service -->
      <configuration>
          <system.web>
              <webServices>
                  <soapExtensionTypes>
                      <add type=
                      "Microsoft.Web.Services2.WebServicesExtension,
                      Microsoft.Web.Services2, Version=2.0.0.0,
                      Culture=neutral,
                      PublicKeyToken=31bf3856ad364e35" 
                      priority="1" group="0" />
                  </soapExtensionTypes>
              </webServices>
          </system.web>
      </configuration>
      
  4. Add using statements for WSE-related namespaces.

    1. In Solution Explorer, right-click MyDimeService.asmx, and then click View Code.

    2. At the top of the file, add the following using statements:

      Imports Microsoft.Web.Services2.Dime
      Imports Microsoft.Web.Services2
      Imports System.Net
      
      using Microsoft.Web.Services2.Dime;
      using Microsoft.Web.Services2;
      using System.Net;
      
  5. Create an image file to be read by the MyDimeService Web service.

    1. In Windows Explorer, create a C:\Images directory.
    2. Find an image and save it as Test.gif to the Images directory, so the full path is C:\Images\Test.gif.
  6. Add the DIME method.

    1. In the MyDimeService class, add the CreateDimedImage Web method declaration and body, and then apply the WebMethod attribute.

      Note

      When you add attachments to a SOAP message that are sent to a Web service, you specify the attachment by calling the Add method of the Attachments property of SoapContext. If you call more than one Web service method by using the proxy class, you must call the Attachments.Clear method after each call, and then add the attachments that are necessary for each individual call.    

      ' The CreateDimedImage Web service returns an image in a DIME
      ' attachment.
      <WebMethod()>  _
      Public Sub CreateDimedImage()
          Dim respContext As SoapContext = ResponseSoapContext.Current
          Dim dimeAttach As New DimeAttachment ("image/gif", _
           TypeFormat.MediaType, "C:\images\test.gif")
          respContext.Attachments.Add(dimeAttach)
      End Sub 
      
      // The CreateDimedImage Web service returns an image in a DIME
      // attachment.
      [WebMethod]
      public void CreateDimedImage()
      {
          SoapContext respContext = ResponseSoapContext.Current;
          DimeAttachment dimeAttach = new DimeAttachment(
              "image/gif", TypeFormat.MediaType,
              @"C:\images\test.gif");
          respContext.Attachments.Add(dimeAttach);
      }
      

To create a Windows Forms client that can consume a DIME message containing an image attachment and display the image

  1. In Visual Studio .NET 2003, create a .Windows Forms application.

    1. On the File menu, point to New, and then click Project.
    2. In the Project Types pane, select Visual C# Projects.
    3. In the Templates pane, select Windows Application.
    4. In the Name box, enter DimeClient for the name of the application.
    5. Click OK.
      The DimeClient project is added to the solution. The Windows Forms Designer appears in the development environment.
  2. Add references to the Microsoft.Web.Services2 and System.Web.Services assemblies.

    1. In Solution Explorer, right-click References, and then select Add Reference.
    2. On the .NET tab, select Microsoft.Web.Services2.dll, and then click Select.
    3. On the .NET tab, select System.Web.Services.dll, and then click Select.
    4. Click OK.
  3. Create a proxy for the DIME Web service.

    1. In Solution Explorer, right-click References, and then select Add Web Reference.
    2. In the Address window, enter https://localhost/DimeGen/MyDimeService.asmx, and then click the arrow icon.
    3. Click Add Reference.
  4. Edit the proxy class to derive from WebServicesClientProtocol.

    1. In Solution Explorer, right-click the Reference.cs file for the Web reference just added, and then click View Code.

      Note

      If the Reference.cs file containing the proxy class is not visible, click the Show All Files icon on the Solution Explorer toolbar, and then expand the Reference.map node.

    2. Change the base class of the MyDimeService proxy to Microsoft.Web.Services2.WebServicesClientProtocol.
      The edited class declaration should read as follows:

      Public Class MyDimeService
        Inherits WebServicesClientProtocol
      
      public class MyDimeService : WebServicesClientProtocol {
      
    3. At the top of the file, add the following using statements:

      Imports Microsoft.Web.Services2
      
      using Microsoft.Web.Services2;
      
  5. Add a using statement for the proxy class.

    1. In Solution Explorer, right-click Form1.cs, and then click View Code.

    2. At the top of the file, add the following using statement:

      Imports DimeClient.localhost
      
      using DimeClient.localhost;
      
  6. Add controls to the form.

    1. In Solution Explorer, right-click Form1.cs, and then select View Designer.
    2. Add a PictureBox control to the form, and then for the PictureBox control:
    • Set the Name property to pbDime.
    • Set the SizeMode property to AutoSize.
    • Set the BorderStyle property to FixedSingle.
    1. Add a Button control to the form, and then for the Button control:
    • Set the Name property to btnGetImage.
    • Set the Text property to Get Image.
  7. Add code to call the Web service and display the image.

    1. Double-click btnGetImage (the button with the Get Image text on it).

    2. Insert code in the body of the btnGetImage_Click method to call the Web service and display the image.

      Sub btnGetImage_Click(sender As Object, e As System.EventArgs)
          Dim svc As MyDimeServiceWse = New MyDimeServiceWse()
          svc.CreateDimedImage()
          If svc.ResponseSoapContext.Attachments.Count = 1 Then
              MessageBox.Show("Got it!")
              pbDime.Image = New Bitmap( _
                svc.ResponseSoapContext.Attachments(0).Stream)
          End If
      End Sub 
      
      private void btnGetImage_Click(object sender, System.EventArgs e) 
      {
          MyDimeServiceWse svc = new MyDimeServiceWse();
          svc.CreateDimedImage();
          if (svc.ResponseSoapContext.Attachments.Count == 1)
              {
              MessageBox.Show("Got it!\n");
              pbDime.Image = new Bitmap(
                  svc.ResponseSoapContext.Attachments[0].Stream);
              }  
      }
      
  8. Run the application (press F5), and then click Get Image on the form to see the image delivered by the CreateDimedImage Web service.

See Also

Other Resources

Programming with WSE