Десериализация XML возвращает пустой массив, хотя POCO имеет правильные атрибуты xml, сгенерированные с помощью инструмента xsd2code++.

Я использую инструмент XSD2Code++ 2019 для визуальной студии для создания POCO из набора из 5 xsd. Я добавил класс POCO ниже. Я вижу, что у него есть правильные декораторы xml для правильной сериализации. Но я действительно не могу понять или понять, почему объект 3-го уровня в возвращаемых десериализованных данных всегда пуст и не приведен к правильному типу.

Я также пытался изменить атрибуты на xmlArray и xmlArrayElement, но ничего из этого не сработало.

Класс POCO — https://gist.github.com/nimisha84/b86a4bb2bf37aea6ec351a9f6e331bed

Пример ответа xml, который имеет нулевые значения после десериализации с использованием кода С#.

<?xml version="1.0" encoding="UTF-8"?>
    <IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2019-07-05T14:29:08.603-07:00">
   <QueryResponse startPosition="1" maxResults="1" totalCount="1">
  <Invoice domain="QBO" sparse="false">
     <Id>8633</Id>
     <SyncToken>14</SyncToken>
     <MetaData>
        <CreateTime>2019-01-09T11:32:12-08:00</CreateTime>
        <LastUpdatedTime>2019-06-05T12:49:40-07:00</LastUpdatedTime>
     </MetaData>
     <CustomField>
        <DefinitionId>1</DefinitionId>
        <Name>CustomPO</Name>
        <Type>StringType</Type>
        <StringValue>Gold</StringValue>
     </CustomField>
     <DocNumber>2830</DocNumber>
     <TxnDate>2019-01-09</TxnDate>
     <CurrencyRef name="United States Dollar">USD</CurrencyRef>
     <ExchangeRate>1</ExchangeRate>
     <PrivateNote>Voided - Voided</PrivateNote>
     <Line>
        <Id>1</Id>
        <LineNum>1</LineNum>
        <Description>Description</Description>
        <Amount>0</Amount>
        <DetailType>SalesItemLineDetail</DetailType>
        <SalesItemLineDetail>
           <ItemRef name="Name27140">815</ItemRef>
           <Qty>0</Qty>
           <TaxCodeRef>NON</TaxCodeRef>
        </SalesItemLineDetail>
     </Line>
     <Line>
        <Amount>0</Amount>
        <DetailType>SubTotalLineDetail</DetailType>
        <SubTotalLineDetail />
     </Line>
     <TxnTaxDetail>
        <TotalTax>0</TotalTax>
     </TxnTaxDetail>
     <CustomerRef name="a4">2561</CustomerRef>
     <DueDate>2019-01-09</DueDate>
     <TotalAmt>0</TotalAmt>
     <HomeTotalAmt>0</HomeTotalAmt>
     <ApplyTaxAfterDiscount>false</ApplyTaxAfterDiscount>
     <PrintStatus>NeedToPrint</PrintStatus>
     <EmailStatus>NotSet</EmailStatus>
     <Balance>0</Balance>
     <Deposit>0</Deposit>
     <AllowIPNPayment>false</AllowIPNPayment>
     <AllowOnlinePayment>false</AllowOnlinePayment>
     <AllowOnlineCreditCardPayment>false</AllowOnlineCreditCardPayment>
     <AllowOnlineACHPayment>false</AllowOnlineACHPayment>
  </Invoice>
   </QueryResponse>
</IntuitResponse>

Код для десериализации-

string responseText = apiResponse.ReadToEnd();
var responseSerializer = new XmlObjectSerializer();
IntuitResponse restResponse = 
(IntuitResponse)this.responseSerializer.Deserialize<IntuitResponse>(responseText);
res=restResponse.Items[0] as QueryResponse;

здесь QueryResponse не возвращает объект Invoice (типа IntuitEntity). Вместо этого возвращается пустое значение. Смотрите скриншот. https://imgur.com/a/5yF6Khb

Мне действительно нужна помощь, чтобы понять, почему свойство 3-го уровня возвращается как пустое.


person Nemo    schedule 06.07.2019    source источник
comment
Ваш второй ответ был удален Бхаргавом Рао пару часов назад. Когда вы используете в сериализации xml XmlArrayItem, вам нужны два уровня тегов xml, таких как Lines и Line. В вашем коде есть только один тег, поэтому вам нужно использовать XmlElement только с Line в моем решении.   -  person jdweng    schedule 08.07.2019
comment
@jdwend попробовал ваше предложение, а также сравнил его с классом, который генерирует Visual Studio. Обнаружена проблема в том, что базовый класс не транслируется в производные, даже если присутствует тег XmlInclude. Придется еще исследовать, почему так происходит. Если я добавлю все типы Include IntuitEntity непосредственно в QueryResponse List‹objects›, он будет работать нормально, но не в том случае, если присутствует прямой XmlElement IntuitEntity. Это может быть проблема с некорректным переводом типа List‹objects›. Проверим еще,   -  person nimisha shrivastava    schedule 09.07.2019


Ответы (1)


Я протестировал код ниже, и он работает. Я вручную создал классы, которые дают более простые результаты, чем использование инструментов.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            string responseText = File.ReadAllText(FILENAME);
            StringReader reader = new StringReader(responseText);

            XmlReader xReader = XmlReader.Create(reader);
            XmlSerializer serializer = new XmlSerializer(typeof(IntuitResponse));

            IntuitResponse response = (IntuitResponse)serializer.Deserialize(xReader);
        }
    }
    [XmlRoot(ElementName = "IntuitResponse", Namespace = "http://schema.intuit.com/finance/v3")]
    public class IntuitResponse
    {
        [XmlAttribute("time")]
        public DateTime time { get; set; }

        [XmlElement(ElementName = "QueryResponse", Namespace = "http://schema.intuit.com/finance/v3")]
        public QueryResponse response { get; set; }
    }

    public class QueryResponse
    {
        [XmlAttribute("startPosition")]
        public int startPosition { get; set; }
        [XmlAttribute("maxResults")]
        public int maxResults { get; set; }
        [XmlAttribute("totalCount")]
        public int totalCount { get; set; }

        [XmlElement(ElementName = "Invoice", Namespace = "http://schema.intuit.com/finance/v3")]
        public Invoice invoice { get; set; }
    }
    public class Invoice
    {

        [XmlAttribute("domain")]
        public string domain { get; set; }
        [XmlAttribute("sparse")]
        public Boolean sparse { get; set; }

        public int Id { get; set; }
        public int SyncToken { get; set; }

        [XmlElement(ElementName = "MetaData", Namespace = "http://schema.intuit.com/finance/v3")]
        public MetaData metaData { get; set; }

        [XmlElement(ElementName = "CustomField", Namespace = "http://schema.intuit.com/finance/v3")]
        public CustomField customField { get; set; }
        public int DocNumber { get; set; }
        public DateTime TxnDate { get; set; }

        [XmlElement(ElementName = "CurrencyRef", Namespace = "http://schema.intuit.com/finance/v3")]
        public CurrencyRef currencyRef { get; set; }
        public int ExchangeRate { get; set; }
        public string PrivateNote { get; set; }
        [XmlElement(ElementName = "Line", Namespace = "http://schema.intuit.com/finance/v3")]
        public List<Line> line { get; set; }

        [XmlElement(ElementName = "TxnTaxDetail", Namespace = "http://schema.intuit.com/finance/v3")]
        public TxnTaxDetail txnTaxDetail { get; set; }

        [XmlElement(ElementName = "CustomerRef", Namespace = "http://schema.intuit.com/finance/v3")]
        public CustomerRef CustomerRef { get; set; }

        public DateTime DueDate { get; set; }
        public int TotalAmt { get; set; }
        public int HomeTotalAmt { get; set; }
        public Boolean ApplyTaxAfterDiscount { get; set; }
        public string PrintStatus { get; set; }
        public string EmailStatus { get; set; }
        public int Balance { get; set; }
        public int Deposit { get; set; }
        public Boolean AllowIPNPayment { get; set; }
        public Boolean AllowOnlinePayment { get; set; }
        public Boolean AllowOnlineCreditCardPayment { get; set; }
        public Boolean AllowOnlineACHPayment { get; set; }
    }
    public class MetaData
    {
        public DateTime CreateTime { get; set; }
        public DateTime LastUpdatedTime { get; set; }
    }
    public class CustomField
    {

        public int DefinitionId { get; set; }
        public string Name { get; set; }
        public string Type { get; set; }
        public string StringValue { get; set; }
    }
    public class CurrencyRef
    {
        [XmlAttribute("name")]
        public string name { get; set; }

        [XmlText]
        public string value { get; set; }

    }
    public class Line
    {
        public int Id { get; set; }
        public int LineNum { get; set; }
        public string Description { get; set; }
        public decimal Amount { get; set; }
        public string DetailType { get; set; }

        [XmlElement(ElementName = "SalesItemLineDetail", Namespace = "http://schema.intuit.com/finance/v3")]
        public SalesItemLineDetail salesItemLineDetail { get; set; }
    }
    public class CustomerRef
    {
        [XmlAttribute("name")]
        public string name { get; set; }

        [XmlText]
        public string value { get; set; }
    }
    public class SalesItemLineDetail
    {
        [XmlElement(ElementName = "ItemRef", Namespace = "http://schema.intuit.com/finance/v3")]
        public ItemRef itemRef { get; set; }

        public int Qty { get; set; }
        public string TaxCodeRef { get; set; }
    }
    public class ItemRef
    {
        [XmlAttribute("name")]
        public string name { get; set; }

        [XmlText]
        public string value { get; set; }
    }
    public class TxnTaxDetail
    {
        public int TotalTax { get; set; }
    }
}
person jdweng    schedule 06.07.2019