4
votes

Within a local framework with messages transmitted in XML via pub/sub,I need to be able to consume a number of messages, however, all messages are received as simple text and must be deserialized into objects created by the Xsd tool.

The messages themselves are all derived from a base MessageType element/object, but if I deserialize based on that like so:

XmlSerializer serializer = new XmlSerializer(typeof(MessageType));
XmlReader reader = XmlReader.Create(new StringReader(rawMessage));
MessageType message = (MessageType)serializer.Deserialize(reader);

I receive an error says that the actual element type ("UpdateParameter" say) was not expected.

At moment the only solution I can think of is to use a switch statement:

XmlReader reader = XmlReader.Create(new StringReader(upString));
reader.MoveToContent();
switch (reader.LocalName.ToLower())
{
   case "updateparameter":
      serializer = new XmlSerializer(typeof(UpdateParameter));
      doStuff((UpdateParameter)serializer.Deserialize(xml));
      break;
   case "updateparameterresponse":
      serializer = new XmlSerializer(typeof(UpdateParameterResponse));
      doStuff((UpdateParameterResponse)serializer.Deserialize(xml));
      break;
   case "UpdateStatusResponse":
      serializer = new XmlSerializer(typeof(UpdateStatusResponse));
      doStuff((UpdateStatusResponse)serializer.Deserialize(xml));
      break;
//...etc. Repeat for all possible elements
}

But I'd really rather not do that if there is an elegent solution. What I wanted to do was something like

Type rootType = Type.GetType(reader.localName);// could work if name is right
serializer = new XmlSerializer(typeof(rootType)); // would work
doStuff((rootType)serializer.Deserialize(xml)); // won't work

But as the comments note, it doesn't work at the very least because you can't seem to use a type variable for conversion. Also while the localName of the xml elements does match the Object's local name the method above requires (so far as I understand) the assembly qualified name which is another beast altogether. Note that the ideal case would overload the doStuff method.

Is there an elegant solution to this that I'm missing? Or at least a solution that doesn't involve the endless switch statements?

1
Could you post a snippet of the XML file format?SwDevMan81

1 Answers