Groups | Blog | Home
all groups > dotnet xml > november 2003 >

dotnet xml : XmlSerializer and inherited objects



bluetears76 NO[at]SPAM yahoo.com
11/14/2003 3:08:43 AM
Hi I have a hirachy of classes which are Message(base), then
FileMessage and ChatMessage (extended)

I want to serialize the objects and when i am deserizaling i dont know
if i am getting FileMessage or ChatMessage. So how to get that object
and use it
I have written following code for serialization
public void Send(Message message)
{
NetworkStream netWorkStream=null;
try
{
XmlSerializer serializer=new XmlSerializer(message.GetType());
netWorkStream=new NetworkStream(_clientSocket);
Stream stream=(Stream)netWorkStream;
serializer.Serialize(stream,message);
}
finally
{
netWorkStream.Close();
}
}

It send the message fine.
but when i deseralize the message i dont know which type of message it
is .. i,e, a FileMessage or a ChatMessage so i get an exception

following is the code of deserlizeation
public bool DeserializeMessage(ref NetworkStream networkStream,ref
Message message)
{
XmlSerializer deserializer=null;
bool result=false;
int count=0;
Byte []buffer=new Byte[BUFFER_SIZE];
deserializer=new XmlSerializer(typeof(MessageContainer));
count=networkStream.Read(buffer,0,buffer.Length);
if(count <= 0)
{
message=null;
return false;
}
MemoryStream memoryStream=null;
memoryStream=new MemoryStream(buffer,0,count);
message= ((MessageContainer)deserializer.Deserialize(memoryStream));
//Get An Exception here as the type is ChatMessage and i am expecting
a message
Christoph Schittko [MVP]
11/16/2003 8:51:27 PM
Bluetears76,

I noticed a few things in the code you posted:

* You don't use the same type when you instantiate the XmlSerializer to
serialize and deserialize the message. Both of them should probably look
like:
XmlSerializer = new XmlSerializer( typeof( Message ) );
Maybe it should be typeof( MessageContainer ), but I can't tell without
knowing more.

To make sure that XmlSerializer can process FileMessage and ChatMessage, you
need to decorate the MessageClass with XmlInclude attributes like this:

[XmlInclude( typeof( FileMessage ) )]
[XmlInclude( typeof( ChatMessage ) )]
public class Message{
// ...
}

Alternatively you might be able to do:
public class MessageContainer
{
[XmlElement(typeof(FileMessage))]
[XmlElement(typeof(ChatMessage))]
public Message content;
// other stuff ...
}

* You are instantiating and XmlSerializer for every serialization and
deserialization operation. It's much more efficient to keep the
XmlSerializer around and re-use it.

* You are using ref in your method signatures. Are you going across
AppDomains with these methods? Is there any reason to do that? Crossing
AppDomain boundaries is a very expensive operation. I don't see a reason why
you need to do this here.

* Are you really building a loosely coupled app or is this in a tightly
coupled scenario where the BinaryFormatter might be the better choice. The
decisive criteria here would be: a) do you really need to transmit XML? b)
do both endpoint of the transmission always have the same assemblies with
the serialized types available? If the answer to a) is no and b) is yes then
the BinaryFormatter is the better choice.

--
HTH
Christoph Schittko [MVP]
Software Architect, .NET Mentor


[quoted text, click to view]

AddThis Social Bookmark Button