XML序列化错误-类型'ItemsChoiceType []'的选择标识符'ItemsElementName'的值无效或缺失

时间:2018-08-10 09:23:33

标签: c# xml serialization xmlserializer

我正在尝试序列化要传递给Web服务的对象,并得到上面的错误。我可以在调试时看到对象本身中存在该值,但似乎并没有发现这一点:

string[] tradeAreas = new string[] {"Area1", "Area2", "Area3", "Area4"};
//RetrieveMarketResultsFor
ItemsChoiceType[] choices = new ItemsChoiceType[] { ItemsChoiceType.area };
MarketResultIdentifier mri = new MarketResultIdentifier
{
    ItemsElementName = choices,
    Items = tradeAreas,
    ItemElementName = ItemChoiceType6.applyingDate,
    Item = DateTime.Today.AddDays(-1)
};

var ser = new XmlSerializer(typeof(MarketResultIdentifier));
using (var stream = new FileStream("mri.xml", FileMode.Create))
    ser.Serialize(stream, mri);

Web服务生成的代码具有以上代码中使用的以下类:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3130.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:openaccess")]
public partial class MarketResultIdentifier : OpenAccessAbstractObject {

    private string[] itemsField;

    private ItemsChoiceType[] itemsElementNameField;

    private object itemField;

    private ItemChoiceType6 itemElementNameField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("area", typeof(string))]
    [System.Xml.Serialization.XmlElementAttribute("areaNames", typeof(string))]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
    public string[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemsChoiceType[] ItemsElementName {
        get {
            return this.itemsElementNameField;
        }
        set {
            this.itemsElementNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("applyingDate", typeof(System.DateTime), DataType="date")]
    [System.Xml.Serialization.XmlElementAttribute("auctionIdentification", typeof(AuctionIdentification))]
    [System.Xml.Serialization.XmlElementAttribute("deliveryDay", typeof(System.DateTime), DataType="date")]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
    public object Item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemChoiceType6 ItemElementName {
        get {
            return this.itemElementNameField;
        }
        set {
            this.itemElementNameField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3130.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:openaccess", IncludeInSchema=false)]
public enum ItemsChoiceType {

    /// <remarks/>
    area,

    /// <remarks/>
    areaNames,
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3130.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:openaccess", IncludeInSchema=false)]
public enum ItemChoiceType6 {

    /// <remarks/>
    applyingDate,

    /// <remarks/>
    auctionIdentification,

    /// <remarks/>
    deliveryDay,
}

尝试进行ser.serialize时在线失败。...

任何帮助表示赞赏:)

解决方案 原来这只是我愚蠢的原因!感谢@dbc指出这一点。我的tradeAreas数组中有4个项目(我在这里使用了错误的数组),它应该只有一个!

2 个答案:

答案 0 :(得分:1)

当您使用XmlChoiceIdentifierAttributechoice元素序列反序列化为某种共享数据类型(此处为string)时,您需要添加两个数组您的数据模型:

  1. 一个属性,该属性返回适当类型的对象数组以捕获选择元素内容,此处是tradeAreas数组中的四个字符串值。

    第一个数组必须标记为[XmlChoiceIdentifier(name)],其中name是第二个数组的名称,以及每个可能选择元素名称的[XmlElement(elementName)]属性。

  2. 还有一个属性,该属性返回一个枚举数组来捕获选择元素名称,此处为每个元素的<area>

    此数组必须标记为[XmlIgnore]

最后,由于第二个数组捕获了第一个数组中元素内容的元素名称,因此这些数组必须具有1-1对应关系。因此choices必须初始化为与tradeAreas相同的长度,例如如下:

var tradeAreas = new string[] {"Area1", "Area2", "Area3", "Area4"};
var choices = Enumerable.Repeat(ItemsChoiceType.area, tradeAreas.Length).ToArray();

在示例代码中,tradeAreas有四个条目,而choices只有一个条目,导致您看到异常。

工作示例.Net小提琴here

有关使用XmlSerializer绑定到XML选择元素的文档,请参见Choice Element Binding Support: Differentiating by NameXmlChoiceIdentifierAttribute Class: Remarks。有关简单的手动示例,请参见this answer How to Serialize List<T> property in c# without showing its type in XML serialization

答案 1 :(得分:0)

只要添加以下内容,您就可以发布代码作品:

    string[] tradeAreas = null;

    public class AuctionIdentification
    {
    }
    public class OpenAccessAbstractObject
    {
    }