Как десериализовать вложенный массив из xml в c # объект? - PullRequest
0 голосов
/ 24 октября 2019

Я пытаюсь десериализовать следующий soap xml ответ от моего веб-сервиса на C# объект:

    <?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Body>
    <ns2:ExportPositionsQueryResponse xmlns:ns2="http://ns" xmlns:ns3="http://nscpm/datatypes/schema/v2011_06_01" xmlns="http://nscpmexportvalue/schema/v2011_06_01">
      <ns2:Positions>
        <FieldTypes>
          <FieldType ExtId="PF_NAME" Type="string"></FieldType>
          <FieldType ExtId="POSITION_QUANTITY" Type="double"></FieldType>
          <FieldType ExtId="INST_NAME" Type="string"></FieldType>
          <FieldType ExtId="INST_TYPE" Type="string"></FieldType>
          <FieldType ExtId="POSITION_TYPE" Type="string"></FieldType>
          <FieldType ExtId="POSITION_CLASS" Type="string"></FieldType>
        </FieldTypes>
        <Position>
          <Field ExtId="INST_NAME" Value="name"></Field>
          <Field ExtId="INST_TYPE" Value="asd"></Field>
          <Field ExtId="PF_NAME" Value="ads"></Field>
          <Field ExtId="POSITION_CLASS" Value="asd"></Field>
          <Field ExtId="POSITION_TYPE" Value="asd"></Field>
          <Field ExtId="POSITION_QUANTITY" Value="asd"></Field>
        </Position>
        <Position>
          <Field ExtId="INST_NAME" Value="asd"></Field>
          <Field ExtId="INST_TYPE" Value="asd"></Field>
          <Field ExtId="PF_NAME" Value="asd"></Field>
          <Field ExtId="POSITION_CLASS" Value="ads"></Field>
          <Field ExtId="POSITION_TYPE" Value="NORMAL"></Field>
          <Field ExtId="POSITION_QUANTITY" Value="asd"></Field>
        </Position>
        <Position>
</ns2:Positions>
    </ns2:ExportPositionsQueryResponse>
  </soap:Body>
</soap:Envelope>

После десериализации xmlSerializer создает объект только с элементом FieldTypes ипоследний элемент Position. Я думаю, что XmlSerializer имеет проблему с вложенным Array(PositionField[][] Position) и не может десериализовать все элементы массива Position. Вот часть моего C# класса объектов, который я использую для десериализации:

    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ns")]
    public partial class ExportPositionsQueryResponsePositions
    {
        private FieldTypesFieldType[] fieldTypesField;

        private PositionField[][] positionField;

        [System.Xml.Serialization.XmlArrayAttribute(Namespace = "http://ns")]
        [System.Xml.Serialization.XmlArrayItemAttribute("FieldType", IsNullable = false)]
        public FieldTypesFieldType[] FieldTypes
        {
            get
            {
                return this.fieldTypesField;
            }
            set
            {
                this.fieldTypesField = value;
            }
        }
        [System.Xml.Serialization.XmlArray(ElementName ="Position",Namespace = "http://ns")]
        [System.Xml.Serialization.XmlArrayItem("Field", typeof(PositionField[]), IsNullable = false)]
        public PositionField[][] Position
        {
            get
            {
                return this.positionField;
            }
            set
            {
                this.positionField = value;
            }
        }
    }

Для создания этого класса я использовал функцию «Специальная вставка» в Visual Studio. Но и с инструментом svcutil возникает та же проблема.

1 Ответ

0 голосов
/ 25 октября 2019

Я решил проблему. Я должен редактировать автоматически сгенерированный класс прокси-клиента. Я заменил все nested arrays [][] на List<T>, и сериализация снова работает. Вот пример:

неправильно сгенерированная часть кода:

private PositionField[][] positionField;

public PositionField[][] Position
    {
        get
        {
            return this.positionField;
        }
        set
        {
            this.positionField = value;
        }
    }

отредактированная часть кода:

 private List<PositionField> positionField;

 public List<PositionField> Position
    {
        get
        {
            return this.positionField;
        }
        set
        {
            this.positionField = value;
        }
    }
...