4

I have an XML and the content is

<Contracts>
    <Contract EntryType="U" ID="401" GroupCode="1">
    </Contract>
</Contracts>

and I have a class with a list of contracts

[XmlArray("Contracts")]
[XmlArrayItem("Contract", typeof(Contract))]
public List<Contract> Contracts { get; set; }

so when I try to Deserialize this, I got this error:

"There was an error reflecting property 'Contracts'."

Deserialization code:

XmlSerializer reader = new XmlSerializer(typeof(ContractPosting));
xml.Position = 0;
eContractXML = (Contract)reader.Deserialize(xml);

Here are the classes:

public partial class ContractPosting
{
    [XmlArray("Contracts")]
    [XmlArrayItem("Contract", typeof(Contract))]
    public List<Contract> Contracts { get; set; }
}

public class Contract
{
    [XmlAttribute(AttributeName = "ContractID")]
    public System.Nullable<int> ContractID { get; set; }

    [XmlAttribute(AttributeName= "PostingID")]
    public string PostingID { get; set; }

    public EntryTypeOptions? EntryType { get; set; }
} 
abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • 3
    If you look at the `InnerException`, you will get a more detailed error message explaining why it couldn't deserialize. – mellamokb Jan 23 '13 at 18:56
  • 1
    Could you paste in the definition of the class? public class Contract {}...etc. – A-Dubb Jan 23 '13 at 18:58
  • What is the `type` you want to deserialize? Which serializer do you use? – I4V Jan 23 '13 at 19:03
  • public partial class ContractPosting { [XmlArray("Contracts")] [XmlArrayItem("Contract", typeof(Contract))] public List Contracts { get; set; } } public class Contract { [XmlAttribute(AttributeName = "ContractID")] public System.Nullable ContractID { get; set; } [XmlAttribute(AttributeName= "PostingID")] public string PostingID { get; set; } public System.Nullable EntryType { get; set; } } – José Arthur Ortiz Antunes Jan 23 '13 at 19:03
  • The error is with the `Contract` class. Please edit your question to show this class and the inner exceptions. – Richard Schneider Jan 23 '13 at 19:06
  • {"There was an error reflecting property 'Contracts'."} [System.InvalidOperationException]: {"There was an error reflecting property 'Contracts'."} Data: {System.Collections.ListDictionaryInternal} HelpLink: null InnerException: {"There was an error reflecting type 'Entity.Contract'."} Message: "There was an error reflecting property 'Contracts'." – José Arthur Ortiz Antunes Jan 23 '13 at 19:08
  • Source: "System.Xml" StackTrace: " at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)\r\n at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)\r\n – José Arthur Ortiz Antunes Jan 23 '13 at 19:08
  • at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)" TargetSite: {Boolean InitializeStructMembers(System.Xml.Serialization.StructMapping, System.Xml.Serialization.StructModel, Boolean, System.String, System.Xml.Serialization.RecursionLimiter)} – José Arthur Ortiz Antunes Jan 23 '13 at 19:08
  • 2
    I tested your code, and when I went down to the bottom-most InnerException (4 levels deep), I found this error message: `Cannot serialize member 'ContractID' of type System.Nullable``1[System.Int32]. XmlAttribute/XmlText cannot be used to encode complex types.` - which is a duplicate of http://stackoverflow.com/questions/2074240/serializing-a-nullabledatetime-in-to-xml – mellamokb Jan 23 '13 at 19:22

3 Answers3

3

Nullable types cannot be serialised as attributes.

You must either change the Contract class to not use Nullable for the XML attributes or change the XML to write these properties as an XML element.

Try this:

public class Contract { 
  [XmlAttribute(AttributeName = "ContractID")] 
  public int ContractID { get; set; } 

  [XmlAttribute(AttributeName= "PostingID")] 
  public string PostingID { get; set; } 

  public System.Nullable<EntryTypeOptions> EntryType { get; set; } 
}

OR:

public class Contract { 
  public int? ContractID { get; set; } 

  [XmlAttribute(AttributeName= "PostingID")] 
  public string PostingID { get; set; } 

  public System.Nullable<EntryTypeOptions> EntryType { get; set; } 
}
Richard Schneider
  • 34,944
  • 9
  • 57
  • 73
0

Since the root node is <Contracts>, try re-arranging your class to this:

[XmlRoot("Contracts")]
public class ContractPosting {
    [XmlElement("Contract", typeof(Contract))]
    public List<Contract> Contracts { get; set; }
}

When you use XmlArray and XmlArrayItem, they have to both be nested inside of something. But your current XmlArray tag is actually the root node of the XML file, so it needs to be an XmlRoot.

Demo: http://ideone.com/jBSwGx

mellamokb
  • 56,094
  • 12
  • 110
  • 136
  • 1
    Change the `Nullable` to a regular `int` for `ContractID`, or convert it to an element instead of an attribute, and then it should work - see http://stackoverflow.com/questions/2074240/serializing-a-nullabledatetime-in-to-xml – mellamokb Jan 23 '13 at 19:25
0

thanks, the problem was the Nullable type and I solved in this way

[XmlIgnore]
public System.Nullable<int> ContractID { get; set; }


[XmlAttribute("ContractID")]
public int ContractIDxml {
get { return ContractID ?? 00; }
set { ContractID = value; }
}