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

XML Serialization error - Invalid or missing value of the choice identifier 'ItemsElementName' of type 'ItemsChoiceType[]'

我正在尝试序列化要传递给 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 个项目(我在这里使用了错误的数组)它应该只有一个!

如果您添加以下内容,您发布的代码有效:

    string[] tradeAreas = null;

    public class AuctionIdentification
    {
    }
    public class OpenAccessAbstractObject
    {
    }

当您将 XmlChoiceIdentifierAttribute to deserialize a sequence of choice 元素用于某些共享数据类型(此处为 string)时,您需要将 两个 数组添加到您的数据模型:

  1. A 属性 返回适当类型的对象数组以捕获选择元素 contents,这里是 [=] 中的四个字符串值13=]数组。

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

  2. 和一个 属性 返回枚举数组以捕获选择元素 names,此处 <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 fiddle here.

有关使用 XmlSerializer 绑定到 XML 选择元素的文档,请参阅 Choice Element Binding Support: Differentiating by Name as well as XmlChoiceIdentifierAttribute Class: Remarks. For a simple manual example, see e.g. to