Home > Articles > Programming > Windows Programming

  • Print
  • + Share This

.NET SOAP Classes

.NET provides a complex yet elegant system that you can use to implement Web Services. From a programming model perspective, a Web Service in .NET is little more than a method in a class. You simply slap on a couple attributes, and, voila[ag] —you have a Web Service. And that's a good thing. We want that. But it's also nice to look under the hood to see what's running this machine.

The .NET SoapFormatter Class

SoapFormatter is one workhorse .NET SOAP class. Its purpose in life is to format a generic .NET object using a SOAP format, given a stream. The class itself has several methods, but the two most interesting are Serialize() and Deserialize(). Serialize() takes as input both a stream into which the SOAP output will be formatted and an object to format. Deserialize() takes the stream from which an object will be created.

To demonstrate SOAP formatting in .NET, Listing 4.2 provides you with a short C# console application that formats the jagged array example into a SOAP format, saves it to disk, and deserializes the array.

Listing 4.2 SoapFormatter Demonstration

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;

namespace SoapSerializer
{
 /// <summary>
 /// Summary description for SoapSerializerTester.
 /// </summary>
 class SoapSerializerTester
 {
  bool Serialize(string strPath, Object objStuff)
  {
   bool bReturn = true;
   try
   {
   // Create a file stream
   FileStream fstmOutput = new FileStream(strPath,
             FileMode.Create);

   // Create the formatter we'll associate
   // with this stream
   SoapFormatter sfmtFormatter = new SoapFormatter();

   // Serialize and save the object
   sfmtFormatter.Serialize(fstmOutput,objStuff);

   // Close the file stream
   fstmOutput.Close();
   } //try
   catch(Exception e)
   {
   Console.WriteLine("{0}",e.Message);
   bReturn = false;
   } // catch

   return bReturn;
  }

  Object Deserialize(string strPath)
  {
   Object objReturn = null;
   try
   {
   // Create a file stream
   FileStream fstmInput = new FileStream(strPath,
             FileMode.Open);

   // Create the formatter we'll associate
   // with this stream
   SoapFormatter sfmtFormatter = new SoapFormatter();

   // Deserialize and return the object
   objReturn = sfmtFormatter.Deserialize(fstmInput);

   // Close the file stream
   fstmInput.Close();
   } //try
   catch(Exception e)
   {
   Console.WriteLine("{0}",e.Message);
   objReturn = null;
   } // catch

   return objReturn;
  }

  static void Main(string[] args)
  {
   try
   {
   // Create an instance...
   SoapSerializerTester sst1 =
      new SoapSerializerTester();

   // Create a jagged array to serialize/
   // deserialize
   int[][] q = {new int[2], new int[4], new int[3]};
   q[0][0] = 4;
   q[0][1] = 7;
   q[1][0] = 15;
   q[1][1] = 72;
   q[1][2] = 6;
   q[1][3] = 167;
   q[2][0] = 1;
   q[2][1] = 90;
   q[2][2] = 659;

   // Serialize the jagged array
   if ( !sst1.Serialize("c:\\out.txt",(Object)q) )
   {
    Console.WriteLine("Failed to serialize object...");
    return;
   } // if

   int[][] r = (int[][])sst1.Deserialize("c:\\out.txt");
   if ( (Object)r == null )
   {
    Console.WriteLine("Failed to deserialize object...");
    return;
   } // if

   // Write results...
   Console.WriteLine("Result was {0}",r.ToString());
   Console.WriteLine(" [0][0] = {0}",r[0][0]);
   Console.WriteLine(" [0][1] = {0}",r[0][1]);
   Console.WriteLine(" [1][0] = {0}",r[1][0]);
   Console.WriteLine(" [1][1] = {0}",r[1][1]);
   Console.WriteLine(" [1][2] = {0}",r[1][2]);
   Console.WriteLine(" [1][3] = {0}",r[1][3]);
   Console.WriteLine(" [2][0] = {0}",r[2][0]);
   Console.WriteLine(" [2][1] = {0}",r[2][1]);
   Console.WriteLine(" [2][2] = {0}",r[2][2]);
   Console.ReadLine();
   } // try
   catch (Exception e)
   {
   Console.WriteLine("{0}",e.Message);
   } // catch
  }
 }
}

If you run this code and open out.txt, you'll find the SOAP output shown in Listing 4.3.

Listing 4.3 SoapFormatter Output SOAP XML

<SOAP-ENV:Envelope
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:a1="http://schemas.microsoft.com/clr/ns/System">
 <SOAP-ENV:Body>
  <SOAP-ENC:Array SOAP-ENC:arrayType="a1:Int32[][3]">
   <item href="#ref-2"/>
   <item href="#ref-3"/>
   <item href="#ref-4"/>
  </SOAP-ENC:Array>
  <SOAP-ENC:Array id="ref-2" SOAP-ENC:arrayType="xsd:int[2]">
   <item>4</item>
   <item>7</item>
  </SOAP-ENC:Array>
  <SOAP-ENC:Array id="ref-3" SOAP-ENC:arrayType="xsd:int[4]">
   <item>15</item>
   <item>72</item>
   <item>6</item>
   <item>167</item>
  </SOAP-ENC:Array>
  <SOAP-ENC:Array id="ref-4" SOAP-ENC:arrayType="xsd:int[3]">
   <item>1</item>
   <item>90</item>
   <item>659</item>
  </SOAP-ENC:Array>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The output is quite faithful to the SOAP specification! Note that the array is of type Int32 rather than int, but this is a result of .NET serializing .NET datatypes. If the remote Web Service cannot handle Int32 datatypes (or cannot map them to 32-bit integers), you might have to adjust the SOAP packet as it leaves your local machine.

.NET SOAP Framing Classes

We won't discuss all the .NET SOAP packet framing classes in great detail here. We'll save the details for Chapter 6, where you'll see a lot of code that uses those classes as you create Web Services and twiddle with the SOAP formatting without having to drop into raw XML to make changes.

NOTE

These classes are called framing classes because they support the frame, or the layout, of the SOAP packet. This is a contrast to the actual serialization classes that manage the serialization and formatting of data that is to be placed into the SOAP packet (SoapFormatter being one such class).

Nonetheless, Table 4.2 identifies several of the major classes and their uses within the .NET Web Service framework.

Table 4.2 .NET SOAP Packet Framing Classes

Class

Purpose

WebMethodAttribute

Identifies a given class method as one that is specifically anointed with Web Service status and establishes some basic SOAP and WSDL information.

WebServiceAttribute

Identifies a given class as one that supports Web Services and establishes some basic SOAP and WSDL information.

SoapAttribute

Provides default functionality of the SOAP-based attributes (there are several).

SoapBinding

Allows you to tailor several aspects of the SOAP and WSDL XML, such as the SOAP and SOAP Encoding namespaces, the HTTP transport, and the WSDL binding.

SoapBodyBinding

Allows you to tailor other aspects of the SOAP and WSDL XML, such as the WSDL parts and document style (literal or rpc).

SoapExtension

Provides a point of extensibility within the .NET Web Service framework that allows you to access (and modify) the raw SOAP XML.

SoapFault

Encapsulates (and returns to the client) a SOAP fault packet.

SoapHeader

Encapsulates a given SOAP Header entry.

SoapHeaderBinding

Allows you to tailor other aspects of the SOAP and WSDL XML, such as the WSDL parts and the SOAP mustUnderstand status (true or false).

SoapMessage

Encapsulates the SOAP packet (used from within SOAP extensions).

SoapMethodAttribute

Used to tweak the SOAP XML (request and response namespaces and so on). This attribute creates literal SOAP (non–Sections 5/7 formatted). This class is related to SoapRpcMethodAttribute, which gives you the same functionality but uses the rpc WSDL document style (forces use of Sections 5/7 for SOAP serialization).


Other important SOAP classes exist, but these are the common ones that you'll most likely use when creating your .NET Web Services. You'll see these classes again in Chapter 6, where you'll use them when actually creating SOAP packets for transmission to the remote system.

  • + Share This
  • 🔖 Save To Your Account

Related Resources

There are currently no related titles. Please check back later.