Welcome to MSDN Blogs Sign in | Join | Help

Serialization and Types

How does a DataContract type get initialized on the server? When I change the constructor for the type, nothing happens.

Older serializers relied on calling the parameter-less constructor to initialize the type when deserializing data. Data contract types have all of the data members initialized to the default values without a constructor being called. However, you can still introduce callback hooks into the serialization process by decorating methods on your data contract type with attributes. Here's a sample program that shows you exactly what goes on.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Runtime.Serialization;

[DataContract]
public class Data
{
[DataMember]
public int a;

[OnDeserialized]
void OnDeserialized(StreamingContext c)
{
Console.WriteLine("OnDeserialized: {0}", a);
a = 1;
}

[OnDeserializing]
void OnDeserializing(StreamingContext c)
{
Console.WriteLine("OnDeserializing: {0}", a);
a = 2;
}

[OnSerialized]
void OnSerialized(StreamingContext c)
{
Console.WriteLine("OnSerialized: {0}", a);
a = 3;
}

[OnSerializing]
void OnSerializing(StreamingContext c)
{
Console.WriteLine("OnSerializing: {0}", a);
a = 4;
}
}

[ServiceContract]
public interface IService
{
[OperationContract]
void Method(Data d);
}

public class Service : IService
{
public void Method(Data d)
{
Console.WriteLine("Method: {0}", d.a);
}
}

class Program
{
static void Main(string[] args)
{
string address = "http://localhost:8000/";
Binding binding = new BasicHttpBinding();
ServiceHost host = new ServiceHost(typeof(Service));
host.AddServiceEndpoint(typeof(IService), binding, address);
host.Open();
ChannelFactory<IService> factory = new ChannelFactory<IService>(binding);
factory.Open();
IService proxy = factory.CreateChannel(new EndpointAddress(address));
Data d = new Data();
d.a = 5;
proxy.Method(d);
factory.Close();
host.Close();
Console.ReadLine();
}
}

You can try running the program to see the value of the data member at various points in time. If you're still confused, here's exactly what's going on.

  1. The data member on the client is set to 5.
  2. OnSerializing is called and changes the data member from 5 to 4.
  3. OnSerialized is called and changes the data member from 4 to 3. The service doesn't see this because the data has already been serialized. This only changed the value of the data member on the client.
  4. The service is called.
  5. The service initializes the type to its default value, which for the data member is 0.
  6. OnDeserializing is called and changes the data member from 0 to 2.
  7. Deserialization actually occurs and replaces the current value of the data members with the value sent by the client. This means that the data member has changed from 2 back to 4.
  8. OnDeserialized is called and changes the data member from 4 to 1.
  9. The service method is called and sees the value of the data member as 1.

Next time: Keeping up with Extension Versions

Published Monday, November 19, 2007 5:00 AM by Nicholas Allen

Comments

Monday, November 19, 2007 9:04 AM by Rob

# re: Serialization and Types

How does the data contract get instantiated without a constructor being called?

Monday, November 19, 2007 10:09 AM by Jason Haley

# Interesting Finds: November 19, 2007

Monday, November 19, 2007 11:51 AM by Nicholas Allen

# re: Serialization and Types

Hi Rob,

I believe it's this method that gets called to instantiate the object.

http://msdn2.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject.aspx

Monday, November 19, 2007 11:55 AM by Nicholas Allen's Indigo Blog

# Controlling for Clock Skew

Message replay is an attack where a message is presented to a processor more than once in the hopes of

Tuesday, November 20, 2007 12:28 AM by Nen

# re: Serialization and Types

Very intresting, what i dont understand is why is the service instansitated until and unless the OnSerialized method is completed, shouldn't the value from the client be passed after the  OnSerialized method is completed.

Tuesday, November 20, 2007 2:31 PM by Nicholas Allen

# re: Serialization and Types

Hi Nen,

You're actually correct.  The service is not instantiated until OnSerialized returns.  I didn't notice that I had those out of order when I drafted the list.

New Comments to this post are disabled
 
Page view tracker