Scope
- To deserialize an xml from a 3rd party vendor into a strongly typed C# object.
- The xml has a namespace attached.
- No DTD or XSD were provided by vendor.
Steps
XML Schema Definition Tool (Xsd.exe)
Basically 2 command lines I executed:
- I first created the xsd file from a sample xml file that I have.
- Then I created the cs class file for the model by using the xsd scheme.
Model
It is the best to generate model via Xsd tool because it contains a lot of System.Xml.Serialization Attribute that are needed for the serializer. Especially around the namespace area!!
The class file will look something like this. A typical model class with lots of attribute hints.
Serializer
All the hard works were done for generating the model and xml attributes. That left this part a bit simple in comparison. It is a bit similar to Autofac, where the hard works are done at the entity level and the actual conversion is just 1 line of ToEntity().
The code looks like this. Some people managed to do this in 2 lines, but I found 4 lines look pretty neat for readability and my troubleshooting.
Troubleshoot
Unbounded Complex Type Bug
1 of the error that I ran into looks like this.
It is a confirmed Microsoft bug and won't be fixed.
The work around is to change the unbounded or add a dummy element for the complex type.
I added the element and regenerated the model class file, and the serializer is happy again.
The work around is to change the unbounded or add a dummy element for the complex type.
I added the element and regenerated the model class file, and the serializer is happy again.
Xsd generated incorrect schema
The xml schema reverse engineered by using xsd.exe from a sample xml file is slightly incorrect. It predicted I might have multiple child nodes, thus the class generated had all these unnecessary array declaration.
Looks like this.
1: public MyComplexType Notes []
I would not blame the xsd tool but there are some manual works required to fix it. (Or C# code will end up with a lot of .FirstOrDefault()
XElement.Name.LocalName
As described before, there is a fallency of trying to access the element via XElement.Name. This method only works when there is no namespace. Out of curiosity and I read further that the correct way is to use XElement.Name.LocalName. I wouldn't recommend going down this path, but it is interesting to know that how we conventionally accessing an element name incorrectly (when you have namespace).
http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.name%28v=vs.110%29.aspx
No comments:
Post a Comment