Posts Tagged ‘Serialization’

Serialization in WCF–Part I

Posted: September 10, 2011 in .NET, WCF
Tags: ,

In general, when we work with WCF services Serialization/Deserialization is taken care by the framework under the hood.We rarely bother about what serializer is used and how it works.But it’s important to understand this as the message payload generated is fully controlled by serializer you use. So a better understanding of the serialization process /techniques and it’s limitations will help us to design the services better.

WCF uses the System.Runtime.Serialization.DataContractSerializer class for this purpose.The code snippet below uses DataContractSerializer to serialize Plain CLR Object.

class Program 
    { 
        static void Main(string[] args) 
        { 
            Customer c = new Customer() { FirstName = "Sankarsan", LastName = "Bose", Address = "404/6 NSC BOSE ROAD" }; 
            DataContractSerializer ds = new DataContractSerializer(typeof(Customer)); 
            using(var m = new MemoryStream()) 
            { 
                ds.WriteObject(m,c); 
                m.Seek(0,SeekOrigin.Begin); 
                using (var sr = new StreamReader(m)) 
                { 
                    Console.WriteLine(sr.ReadToEnd()); 
                } 
                
            } 
                   Console.Read(); 
        } 
    } 
    public class Customer 
    { 
        public String FirstName { get; set; } 
        public String LastName { get; set; } 
        public String Address { get; set; }

    }


The output will be the following XML string.

<Customer xmlns="http://schemas.datacontract.org/2004/07/SerializationDemo" xmlns:i="'>http://www.w3.org/2001/XMLSchema-instance">

<Address>404/6 NSC BOSE ROAD</Address>

<FirstName>Sankarsan</FirstName>

<LastName>Bose</LastName>

</Customer>

We need to note the following points:

a) The output is XML format

b) A Plain CLR object(POCO) without any additional decoration(attributes) is serialized with Type Name and Properties as XML Elements (This is called inferred data contracts)

c) The xmlns attribute by default is http://schemas.datacontract.org/2004/07/<<CLR Namespace Name>>

d) The ordering of the properties/fields is alphabetically sorted.

e) The XML output does not contain any additional information CLR Datatypes.This is the reason we need to provide the type information while we instantiate the Serializer.

Now if we need to have more fine grained over the serialization output we need to have some mechanism to provide additional inputs to the serializer regarding how we can want to customize our output. The System.Runtime.Serialization.DataContractAttribute and System.Runtime.Serialization.DataMemberAttribute provides the same.

We have used these attributes in the Customer class as shown below:

[DataContract(Name="customer",Namespace="http://sankarsanbose.com/Customer")] 
    public class Customer 
    { 
        [DataMember(Name="firstname",Order=1)] 
        public String FirstName { get; set; } 
        [DataMember(Name = "lastname", Order = 2)] 
        public String LastName { get; set; } 
        [DataMember(Name = "address", Order = 3)] 
        public String Address { get; set; }

    }


The XML output produced is as shown below:

<customer xmlns="http://sankarsanbose.com/Customer" xmlns:i="'>http://www.w3.org/2001/XMLSchema-instance">

<firstname>Sankarsan</firstname>

<lastname>Bose</lastname>

<address>404/6 NSC BOSE ROAD</address>

</customer>

Here we have altered the name of the XML Elements, Namespace and ordering of the elements.

We will play around a little bit with this attributes and let’s remove DataMemberAttribute from one of the properties and make another one private.

[DataContract(Name="customer",Namespace="http://sankarsanbose.com/Customer")] 
public class Customer 
{ 
    [DataMember(Name="firstname",Order=1)] 
    public String FirstName { get; set; } 
    [DataMember(Name = "lastname", Order = 2)] 
    private String LastName { get; set; } 
    public String Address { get; set; }

} 

As the xml output below shows the property(Address) without the DataMemberAttribute is not serialized and the private attribute is serialized with a default NULL value.

<customer xmlns="http://sankarsanbose.com/Customer" xmlns:i="'>http://www.w3.org/2001/XMLSchema-instance">
<firstname>Sankarsan</firstname>
<lastname i:nil="true"/>
</customer>

The default value can be controlled through the EmitDefaultValue parameter of the DataMember attribute.This is true by default and can be turned off as shown below:

[DataContract(Name="customer",Namespace="http://sankarsanbose.com/Customer")]
public class Customer
{
    [DataMember(Name="firstname",Order=1)]
    public String FirstName { get; set; }
    [DataMember(Name = "lastname", Order = 2,EmitDefaultValue=false)]
    private String LastName { get; set; }
    public String Address { get; set; }

}

So the serialized data now no longer emits the lastname with Null value:

<customer xmlns="http://sankarsanbose.com/Customer" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<firstname>Sankarsan</firstname>
</customer>

This post covers the basics and in the next post we will take a deeper look into the DataContractSerializer class.

Advertisements

Yesterday I have come across very interesting question:Should one use raw XML as string or Objects as parameters of methods for passing data between tiers.I mostly use objects for doing so.Initially I had a bias towards that approach.But after pondering over the subject I found that both the approaches has it’s own pros and cons and one should choose based mostly on the non functional requirements(performance/maintainability/developer expertise) for the system under discussion.

Object Approach

Pros

  1. All the advantages of object oriented programming and design can be very well used.Code will be simpler and very easy to understand.
  2. When used in WebMethods the schema will be extracted via wsdl as XSD and it will be easier for the client code to interpret the meaning and purpose of the object.

Cons

  1. When the object is to be passed beyond process/machine boundary it will be serialized.
    • For Web Services .NET Framework will be using the XML Serializer.
    • For Remoting it can be the Binary as well as the SOAP formatter
    • .NET XML Serialization internally generates an assembly at runtime for serialization.There will be one assembly per type passed to the constructor of the XMLSerializer constructor.Naturally there is a performance hit because of this.However this assemblies can be generated before hand using the tool SGen.exe.The detailed tips for improvement of XML Serialization can found in the patterns & practices guide.
  2. For any change in the object structure the proxies needs to updated.

 XML Approach

Pros

  1. No additional serialization overhead.
  2. For any change in the object structure the proxies needs not be updated.However this can sighted as a disadvantage as well as the client contract will hazy.Client has to know before the xml structure.There is should be some XSD validation in the service as well.

Cons

  1. Program will be complex as one has to use XMLDOM and Xpath to parse and read/write the values from/into the XML.

That’s all I can think of at this point.

But I would still prefer objects with XMLSerializer unless my performance requirements vs server infrastructure is not at all able to take the load.