BizTalk Utilities CV ,   Jobs ,   Code library  
 
Home Page
WCF, WS, SOAP
The SoapFormatter
Runtime Object Serialization
Importance of a UDDI based Service Registry
BizTalk and WCF: Part V, Publishing Operations Patterns
BizTalk and WCF: Part IV, Attachment Patterns
BizTalk and WCF: Part III, Transaction Patterns
BizTalk and WCF: Part II, Security Patterns
BizTalk and WCF: Part I, Operation Patterns
Accessing UDDI using Apache Scout APIs
Storing state in an XML property bag
UDDIExplorer
XslTransport for PocketSOAP
Kafka - XSLT SOAP Toolkit
VB Web services Proxy Generator
Using msxml3 with Web Storage System
Getting started with SOAP
Calling an Web service from a Managed C++ project
How to access asyncronously from C# an web service
What is XML-RPC?
Web Service and DHTML
<< Uncategorized
XALAN >>

By :Mark Wilson
I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
First posted :03/24/2008
Times viewed :357

 

Serializing an Object Graph

Object serialization itself is simple. The SoapFormatter class from the System.Runtime.Serialization.Formatters.Soap namespace provides a Serialize() method with the two overloads shown in the table. When we invoke the method, it writes a complete SOAP message with the serialized object inside the body to the current position of the passed in stream.

Table The SoapFormatter offers two versions of the Serialize() method. One produces a simple SOAP message with only a body element, the other allows to us to add headers as well.

Method

Description

public void Serialize( Stream s, object o )

Serializes an object (graph) embedded in the body of a SOAP message into the specified stream.

public void Serialize( Stream s, object o, Header[] headers )

Serializes an object (graph) embedded in the body of a SOAP message into the specified stream. The headers array specifies headers in to include in the SOAP message.

With the second of the two overloads we can create messages containing a header section in addition to the body section for the serialized object. We will see how to use them later.

Both methods can process any object marked with the SerializableAttribute. Unlike the XmlSerializer from chapter 9, the SoapFormatter does not impose any limitations on the objects in can serialize. We can serialize doubly-linked lists, dictionaries and everything else we can think of as long as they can furnish the SerializableAttribute. The SoapFormatter exposes properties (table 13.2) to allow for some customization of the message format and the behavior of the formatter. There is no need for any properties to customize the XML format of the serialized objects, because the SOAP standard defines very clear guidelines for the format of serialized objects inside a message. Moreover, the goal of runtime serialization is to ensure that a serialized object is always deserialized to the same type. Ideally the serialization format is never an issue because nobody other than a SoapFormatter ever looks at the serialized data. The XmlSerializer on the other hand does not guarantee nor mandate that the serialized data is deserialized to the same object type. Its focus is on interoperability and allows deserialization to a different type as long as the XML format is compatible with the format of the original class.

 

The little customization of the serialization format possible is done through the ISerializable interface or registered SerializationSurrogates.

Table The SoapFormatter exposes several property to customize the generated message. These properties apply to the format of the message, not the format of the serialized object.

Property

Type

Description

AssemblyFormat

FormatterAssemblyStyle

Controls the format of assembly references in the generated SOAP message. The references are used to locate assemblies when an object is deserialized.

Binder

SerializationBinder

Customizes how types and assembly references in a SOAP message map to installed assemblies. We can assign a custom SerializationBinder for unavailable types or assemblies or changes in namespaces or type names.

Context

StreamingContext

Contains information about the destination of the serialized message. It is passed to objects that handle their own serialization through ISerializable.

See previous chapter for more information.

SurrogateSelector

ISurrogateSelector

Registers substitutes to control the serialization process for certain types.

See previous chapter for more information.

TopObject

ISoapMessage

Sets the ISoapMessage to receive the data in a deserialized RPC-style message. See chapter 14 for details.

TypeFormat

FormatterTypeStyle

Controls when object reference identifiers are generated in the SOAP message.

Developing the Sender class

Now that we know the Serialize() method we can start with the first part of our example application: A sender class to hide all the details of serializing objects and sending messages behind an easy-to-use interface. It is shown in Listing

Listing The SoapMessageSender class send objects encoded as SOAP messages to message queues.

using System;

using System.IO; // for Stream

using System.Messaging; // for Message and MessageQueue

using System.Runtime.Serialization.Formatters.Soap;

public class SoapObjectSender

{

  private MessageQueue _DestinationQueue;

  private SoapFormatter _Formatter = new SoapFormatter();

  public SoapObjectSender(string destinationQueueName ){

    _DestinationQueue = new MessageQueue(destinationQueueName);

    _Formatter = new SoapFormatter();          |#1

  }

  public void SendObject( object o ){

    Message msg = new Message();                 |#2

    _Formatter.Serialize( msg.BodyStream, o );   |

    _DestinationQueue.Send( msg );

  }

}

(annotation) <#1 Instantiate a new SoapFormatter and keep it around for the lifetime of the sender.>

(annotation) <#2 The Serialize method can serialize the object directly into the message through the BodyStream property.>

Each SoapObjectSender object creates a SoapFormatter that it will use to send all objects. Instantiating a SoapFormatter is not expensive operation, but keeping one around will save some cycles if we send more than one message. In the same vein, we designed the SoapObjectSender to send messages always to the same queue to reduce any overhead associated with opening and closing a queue.

Once we have instantiated a sender object, we can call SendObject() to send objects packaged up in SOAP messages. All we have to do is to pass in the object we want to send, SendObject() does the rest.

Developing the Message classes

Now that we have a sender, we need something to send. Since we are building an application to asynchronously perform jobs in a user management system, we need a user class to encapsulate the user data and a job class to encode the action to perform when the management application processes the received message.

Listing The User class stores user data

namespace Christoph.SoapMQ.Shared

{

  [Serializable]

  public class User {  

    public User(string name, int id) {

      _Id = id;

      _Name = name;

    }

    private int _Id;

    private string _Name;

    public int Id { get { return _Id; } }

    public string Name { get { return _Name; } }

    …

  }

} // namespace

Because we are trying to keep the example simple our user class only contains two fields and two read-only properties: One to store the user’s name and one for a numeric id. This simplistic user class still has an interesting twist to it. The int type is a value type in the .NET type system, string is a reference type. Keep this in mind until we look at the serialized object.

The user class does not perform any operations specific to user management. These operations are implemented in separate job classes. Our application transmits job objects via message queues to an application that executes each received object in a batch fashion. Now let’s look at the job class to insert a new user into the system.

Listing An InsertJob object will insert a new user into the system when the Run method is executed

namespace Christoph.SoapMQ.Shared

{

  [Serializable]

  public class InsertJob : IQueuedJob

  {

    private User _NewUser;

    public InsertJob(User newUser) {

      _NewUser = newUser;

    }

    public void Run(){ // defined by IQueuedJob

      // Insert the new user into the system

      Console.WriteLine("Inserting new user");

    }

  }

} // namespace


Rate this article on a scale of 1 to 10

Your vote :  


 

Recent Jobs

Software Developers Needed in Charl
Sr. Software Engineer - Analytics
Immediate Mainframe openings for Ch
Immediate TANDEM-TAL openings for C
Immediate ASP.NET/C# Openings for C

View all Jobs (Add yours)
View all CV (Add yours)



efax
swimming pool contractor
reservationless conference calls
water softener
Teleconference
Host Department NOLIMIT Web Hosting
MSN
sunglasses


    Email TopXML  

Front Page Daily Stuff TopXML Forum XML blogs XML Newsgroups BizTalk Biztalk Utilities Biztalk Utilities Tutorial B2B SAP XML Microsoft .NET Dotnet System XML Soapformatter SQLXML XMLserializer XQuery PHP PHP SimpleXML PHP XML Dom PHP XML RPC PHP XSLT Java Java Java XML Xalan Microsoft ASP ASP Schemas XML SQL Server XML XMLDom XSL XSL Tutorial XSLT Stylesheets General Javascript CSS XHTML WAP