views:

267

answers:

5

I'm working on a .NET project that integrates with an external company. This company will be sending us XML messages via HTTP POST (raw XML, not SOAP). There are basically three different types of XML messages they will be sending us, which all have their own XSDs. There is no inheritance hierarchy between these XSDs, they are all basically standalone XML "entities."

Right now, we are just using an IHttpHandler .ashx class to process the XML. We created a class from each XSD, and are using XmlSerializer to convert the different XML messages to objects. This is not ideal, because we need to know the type of message before creating the appropriate XmlSerializer to process it. We are currently just looking at the root element name in the message to choose which type to pass to the XmlSerializer.

There has to be a better way to do this... Is there something in WCF that can do this automatically with plain XML? Or is there an XML serializer available that can dynamically serialize multiple types? Any other suggestions?

A: 

Why not read it into a dataset with XmlReadMode.Auto? Then you've got one object that can be read as appropriate - you can look at Table[0] to see which one you've got.

R Ubben
Not all XML can be read into a DataSet.
John Saunders
That is true, of course. But he did say that he used the xsd to create classes. That implied to me that the xml was probably not complex enough to preclude using a dataset. It will not work with all XML, but if it does, there are considerable advantages - sorting, ease of display of the results, and so on.
R Ubben
The only XSD that can represent data that can be loaded into a DataSet is an XSD that was created to represent a DataSet. XSD is much more general than the tiny subset used by the DataSet Designer in Visual Studio.
John Saunders
Not necessarily true. I have one application doing this with XML coming to me through a socket from an app running on a Sun machine, and another coming over http post from an app running in MVS from a mainframe. Neither XSD was designed for a .Net dataset, and both do read correctly, tens of thousands of times a day for years now. Not all XML can be read this way - the IFX xsd is way beyond the capability of a dataset, for example - but it is surprising just how much it can handle. You just have to try it and see. If it works, fine; if not, you do something different.
R Ubben
+1  A: 

WCF as RESTful+POX

REST and POX
REST in Windows Communication Foundation (WCF)

Matthew Whited
+1  A: 

The only problem I have with XMLSerializer is that it's pretty brittle. Change the XML for more features and you might break clients. I think it's better to parse the XML yourself. Maybe using Linq XDocument/XElement?

Keltex
I would stay away from the XML Serializer if at all possible. It's not only "brittle", it's also not general enough, and is nearing end of it's useful life. I haven't seen many recent Connect defects for the XML Serializer answered as "yes, this is a bug, and we'll fix it".
John Saunders
Brittle is as Brittle does. If you design your types with the appropriate xsd:any the XML Serializer, on the client or server side, will be robust in the face of changes in XML. And "nearing end of it's useful life" is not accurate. The XML Serializer is and remains part of the .NET BCL and inherits the support policy of same. It will be around, and supported, for the next 10 years at least.
Cheeso
Sure 'bout that? There's "supported" and "supported".
John Saunders
+1  A: 

The Linq to XML classes are very flexible and easy to use. You can just new up an XElement and throw in your XML string.

XElement xml = XElement.Parse(receivedXmlString);

Job done.

Anders Heijlsberg presented a good session on this at MIX07, "Using LINQ to Dramatically Improve Data Driven Development in Web Applications". You might find the video useful. The Linq to XML stuff is about 26 minutes in.

Tim Long
A: 

I would use the XML Serializer, just in a more general way than you are currently doing.

If the message can be one of three types, you can still use the XML Serializer to read and deserialize automatically - you do not need to check the first element to distinguish between them. But it requires you to merge the XSDs into a single consolidated XSD and then produce a single consolidated "union" type on the .NET side. You can also do this the round-about way by merging the generated types, and then deriving a generated XSD from that using the xsd.exe tool.

The alleged "brittleness" of the XML Serializer is a non-issue in my opinion. XML in general can be brittle, if you use an XML databinding technology that depends on XSD, as does XML Serialization. It is not XML Serialization per se, that is brittle. IT is the schema that can be brittle. Schema-based approaches - including the XML Serialization in .NET - can be brittle if the schema themselves have not been designed with evolution in mind. Eg, appropriate use of xsd:any and xsd:xmlAny, message version tags, etc. The good news is there is good guidance for designing flexible schema that can evolve gracefully.

However, this all may be a non-issue because the schema already exist. In any case, you will not add "brittleness" to the system by using XML Serializer.

Cheeso