Locked Deserialization of more than one type?

  • Friday, April 06, 2012 6:50 PM
     
      Has Code

    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 AM
    Moderator
     
     
    Please 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
     
      Has Code

    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 PM
    Moderator
     
     
    Can 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
     
      Has Code

    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 AM
    Moderator
     
     
    Suggestion? 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
     
      Has Code

    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 AM
    Moderator
     
      Has Code
        <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


  • Wednesday, April 18, 2012 3:37 PM
     
     
    You don't know what "a better way would be"?

    Kevin Burton

  • Wednesday, April 18, 2012 3:57 PM
    Moderator
     
     
    One 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 PM
    Moderator
     
     

    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