Deserialization of more than one type?
-
Friday, April 06, 2012 6:50 PM
I have a problem that I am hoping for some suggestions for a solution. I have code:
Stream stream = httpResponse.GetResponseStream(); XmlSerializer serializer = new XmlSerializer(typeof(OrderReport));
Basically this gets an XML stream of data from a web server and tries to deserialize it. The problem is that it could be one of two different types which are not related. I tried using the overload (typeof(object), new Type[] { . . . . .} ). But, then I get the exception that anonymous types are not accepted. I tried serializing one type in hopes that if it fails I could rewind the stream and try the other type. But, I get an exception indicating that this stream does not support seeking (setting the Position to zero). If the XML could be one of several types how would be the best way to handle this?
Thank you.
Kevin Burton
All Replies
-
Monday, April 16, 2012 12:07 AMModeratorPlease post your code that isn't working using typeof(object), new Type[] { . . . . .}. That should work if you give a list of named types.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects -
Monday, April 16, 2012 7:52 PM
I used:
XmlSerializer serializer = new XmlSerializer(typeof(object), new Type[] { typeof(OrderReport), typeof(SettlementReport) }); //XmlSerializer serializer = new XmlSerializer(typeof(OrderReport)); object o = null;
and I get the following error:
System.InvalidOperationException: Cannot include anonymous type 'BuySeasons.Amazon.Types.OrderReport'. at System.Xml.Serialization.XmlReflectionImporter.IncludeType(Type type, RecursionLimiter limiter) at System.Xml.Serialization.XmlSerializer..ctor(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, String defaultNamespace, String location, Evidence evidence) at System.Xml.Serialization.XmlSerializer..ctor(Type type, Type[] extraTypes)
Kevin
Kevin Burton
-
Tuesday, April 17, 2012 10:48 PMModeratorCan you post the OrderReport class? It seems strange that an anonymous type should have a name.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects -
Wednesday, April 18, 2012 12:09 AM
Here is the OrderReport class:
[Serializable] [DesignerCategory("code")] [GeneratedCode("xsd", "2.0.50727.3038")] [DebuggerStepThrough] [XmlRoot(Namespace = "", IsNullable = false)] [XmlType(AnonymousType = true)] public class OrderReport { public OrderReport(); public string AmazonOrderID { get; set; } public string AmazonSessionID { get; set; } public OrderReportBillingData BillingData { get; set; } [XmlElement("CustomerOrderInfo")] public OrderReportCustomerOrderInfo[] CustomerOrderInfo { get; set; } public OrderReportFulfillmentData FulfillmentData { get; set; } [XmlElement("Item")] public OrderReportItem[] Item { get; set; } public DateTime OrderDate { get; set; } public DateTime OrderPostedDate { get; set; } }
But I don't think this is relavent. If I just switch the types in the array I get
System.InvalidOperationException: Cannot include anonymous type 'BuySeasons.Amazon.Types.SettlementReport'. at System.Xml.Serialization.XmlReflectionImporter.IncludeType(Type type, RecursionLimiter limiter) at System.Xml.Serialization.XmlSerializer..ctor(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, String defaultNamespace, String location, Evidence evidence) at System.Xml.Serialization.XmlSerializer..ctor(Type type, Type[] extraTypes)
Kevin Burton
-
Wednesday, April 18, 2012 12:40 AMModeratorSuggestion? Remove the "XmlType(AnonymousType=true)" and see what happens.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects -
Wednesday, April 18, 2012 1:37 AM
This is a metadata view of the class. I only have access to the .xsd from which these classes are generated. How would I change the xsd so that the tool 'xsd' doesn't generate the XmlType(AnonymousType=true) attribute?
The SettlementReport looks like:
<xsd:schema id="SettlementReport" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="SettlementReport"> <xsd:complexType> <xsd:sequence> <xsd:element name="SettlementData" type="SettlementData" /> <xsd:element name="Order" type="Order" maxOccurs="unbounded" /> <xsd:element name="Adjustment" type="Adjustment" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> </xsd:element>
The OrderReport looks like (the first part):
<xsd:element name="OrderReport"> <xsd:complexType> <xsd:sequence> <xsd:element ref="AmazonOrderID"/> <xsd:element name="AmazonSessionID"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d{3}-\d{7}-\d{7}"/> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="OrderDate" type="xsd:dateTime"/> <xsd:element name="OrderPostedDate" type="xsd:dateTime"/> <xsd:element name="CustomerOrderInfo" minOccurs="0" maxOccurs="10">
Kevin Burton
- Edited by KevinBurton Wednesday, April 18, 2012 1:43 AM Update
-
Wednesday, April 18, 2012 1:47 AMModerator
<xsd:complexType name="SettlementReportType"> <xsd:sequence> <xsd:element name="SettlementData" type="SettlementData" /> <xsd:element name="Order" type="Order" maxOccurs="unbounded" /> <xsd:element name="Adjustment" type="Adjustment" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> <xsd:element name="SettlementReport" type="SettlementReportType"/>Mind you, I still don't know why it's a problem, and it seems very much like a bug in the XML Serializer. However, since XML Serializer bugs are no longer being fixed, it seems best to find another way.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
- Edited by John SaundersMVP, Moderator Wednesday, April 18, 2012 1:48 AM
-
Wednesday, April 18, 2012 3:37 PMYou don't know what "a better way would be"?
Kevin Burton
-
Wednesday, April 18, 2012 3:57 PMModeratorOne might use the Data Contract Serializer, or one might use LINQ to XML.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects -
Wednesday, April 18, 2012 5:46 PM
Since these classes are generated from the xsd's trying to coerce the xsd tool to decorate it with data contract attributes might be painful. How do I convince ASP Web Services to serialize using a data contract or an XML type the would be acceptable to XDocument and the similar XML class used for LINQ? What serializer would I use to deserialize with LINQ. As far as I know it only reads XML. It doesn't handle deserialization. Right?
By the way unless I am doing something wrong changing the XSD as you outlined above still causes the metadata view of the object to be decorated with XmlType(AnonymousType=true)
Kevin Burton
- Edited by KevinBurton Wednesday, April 18, 2012 5:58 PM Update.
-
Wednesday, April 18, 2012 5:58 PMModerator
You did not say that you were using this with ASMX web services.
Why are you calling the serializer directly, then?
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects -
Thursday, April 19, 2012 2:04 PM
I have two applications both that as far as I see have this same problem. One I receive a stream from a WebService that is of the ContentType application-octet-stream (maybe this isn't exact but it is a "file" binary type content) that I know to be an XML stream of data. The serializer is call directly because I have a stream of XML data that could be serialized into one of two types, as above. The other application reads a column from a database that is on type XML and it basically has to determine the same thing. Which of the possible two objects should this be deserialized to.
Kevin Burton

