【问题标题】:Null object when deserializing C#反序列化 C# 时为空对象
【发布时间】:2021-01-06 17:48:24
【问题描述】:

我正在尝试将 XML 请求转换为 C# 对象,但我不能。我尝试了几种 StackOverFlow 解决方案,但都没有奏效。有谁知道它可能是什么?因为对象上的Header为null,所以请求中的标签比较多,不过我在慢慢组装。

我不知道它是否有区别,但是在 Header 类中我将 XmlRoot 标记更改为 XmlElement 并继续而不反序列化

我有以下文件和函数

文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace BonzayBO.DTO
{
[XmlRoot("Conciliation")]
public class Conciliation
{
    [XmlElement("Header")]
    Header Header { get; set; }
}

  [XmlRoot("Header")]
  public class Header
  {
    [XmlElement("GenerationDateTime")]
    string GenerationDateTime { get; set; }
    [XmlElement("StoneCode")]
    int StoneCode { get; set; }
    [XmlElement("LayoutVersion")]
    int LayoutVersion { get; set; }
    [XmlElement("FileId")]
    int FileId { get; set; }
    [XmlElement("ReferenceDate")]
    string ReferenceDate { get; set; }

  }
}

功能:

public string BuscarConciliacaoDiaCliente()
    {
        using (BDBONZAY bd = new BDBONZAY())
        {
            try
            {
                using (HttpClient requisicao = new HttpClient())
                {
                    var resposta = requisicao.GetAsync("https://gabriel.free.beeceptor.com/bonzay").Result;

                    if (resposta.StatusCode == HttpStatusCode.OK)
                    {
                        var xml = new XmlDocument();
                        xml.LoadXml(resposta.Content.ReadAsStringAsync().Result);
                                                    
                        bd.BeginTransaction();

                        XmlSerializer serializer = new XmlSerializer(typeof(BonzayBO.DTO.Conciliation));
                        using (TextReader reader = new StringReader(resposta.Content.ReadAsStringAsync().Result))
                        {
                            BonzayBO.DTO.Conciliation result = (BonzayBO.DTO.Conciliation)serializer.Deserialize(reader);
                        }
                        
                        bd.CommitTransaction();
                    }
                }
            }
            catch (Exception ex)
            {
                bd.RollbackTransaction();
                throw;
            }
        }
        return "";
    }

XML:

<?xml version="1.0" ?>
<Conciliation>
    <Header>
        <GenerationDateTime>20151013145131</GenerationDateTime>
        <StoneCode>123456789</StoneCode>
        <LayoutVersion>2</LayoutVersion>
        <FileId>020202</FileId>
        <ReferenceDate>20150920</ReferenceDate>
    </Header>
    <FinancialTransactions>
        <Transaction>
            <Events>
                <CancellationCharges>0</CancellationCharges>
                <Cancellations>1</Cancellations>
                <Captures>0</Captures>
                <ChargebackRefunds>0</ChargebackRefunds>
                <Chargebacks>0</Chargebacks>
                <Payments>0</Payments>
            </Events>
            <AcquirerTransactionKey>12345678912356</AcquirerTransactionKey>
            <InitiatorTransactionKey>1117737</InitiatorTransactionKey>
            <AuthorizationDateTime>20150818155931</AuthorizationDateTime>
            <CaptureLocalDateTime>20150818125935</CaptureLocalDateTime>
            <Poi>
                <PoiType>4</PoiType>
            </Poi>
            <EntryMode>1</EntryMode>
            <Cancellations>
                <Cancellation>
                    <OperationKey>3635000017434024</OperationKey>
                    <CancellationDateTime>20150920034340</CancellationDateTime>
                    <ReturnedAmount>20.000000</ReturnedAmount>
                    <Billing>
                        <ChargedAmount>19.602000</ChargedAmount>
                        <PrevisionChargeDate>20150921</PrevisionChargeDate>
                    </Billing>
                </Cancellation>
            </Cancellations>
        </Transaction>   
    </FinancialTransactions>
    <Payments>
        <Payment>
            <Id>109863</Id>
            <WalletTypeId>1</WalletTypeId>
            <TotalAmount>840.72</TotalAmount>
            <TotalFinancialAccountsAmount>840.72</TotalFinancialAccountsAmount>
            <LastNegativeAmount>0.00</LastNegativeAmount>
            <FavoredBankAccount>
                <BankCode>1</BankCode>
                <BankBranch>24111</BankBranch>
                <BankAccountNumber>0123456</BankAccountNumber>
            </FavoredBankAccount>
        </Payment>
    </Payments>
    <Trailer>
        <CapturedTransactionsQuantity>2</CapturedTransactionsQuantity>
        <CanceledTransactionsQuantity>2</CanceledTransactionsQuantity>
        <PaidInstallmentsQuantity>3</PaidInstallmentsQuantity>
        <ChargedCancellationsQuantity>1</ChargedCancellationsQuantity>
        <ChargebacksQuantity>2</ChargebacksQuantity>
        <ChargebacksRefundQuantity>1</ChargebacksRefundQuantity>
        <ChargedChargebacksQuantity>1</ChargedChargebacksQuantity>
        <PaidChargebacksRefundQuantity>1</PaidChargebacksRefundQuantity>
        <PaidEventsQuantity>1</PaidEventsQuantity>
        <ChargedEventsQuantity>1</ChargedEventsQuantity>
    </Trailer>
</Conciliation>

【问题讨论】:

  • 您是否还可以添加您尝试反序列化的 XML 结构(resposta.Content.ReadAsStringAsync().Result 的内容?为什么要解析两次响应 - 一次使用 LINQ (XmlDocument.LoadXml),一次使用 XmlSerializer ?
  • 是否故意跳过了标题? XML 文档丢失&lt;?xml version="1.0" ?&gt;?根元素&lt;Conciliation&gt;没有关闭?
  • 奇怪的是,当我编辑帖子时,我可以看到 XML 已正确关闭。在本地修复 XML 文档后,使用 LINQ 加载和解析结构可以正常工作:var xml = XDocument.Load(@"c:\temp\xml1.xml");。使用XmlSerializer它也应该可以工作。
  • 我忘了放标题()。我会把它放在api中,然后再试一次。如果你想测试我已经更新了 API。是的,标签调解已结束
  • 我试着把标题和它继续同样的错误,它不转换

标签: c# .net xml


【解决方案1】:

序列化不起作用,因为您的类成员是 private,而 xml 序列化仅适用于公共成员。您需要进行的第一个更改是使描述 xml 结构的成员公开:

来自docs.microsoft.comClass members can have any of the five kinds of declared accessibility and default to private declared accessibility

public class Conciliation
{
    [XmlElement("Header")]
    public Header Header { get; set; }
}

public class Header
{
    [XmlElement("GenerationDateTime")]
    public string GenerationDateTime { get; set; }
    [XmlElement("StoneCode")]
    public int StoneCode { get; set; }
    [XmlElement("LayoutVersion")]
    public int LayoutVersion { get; set; }
    [XmlElement("FileId")]
    public int FileId { get; set; }
    [XmlElement("ReferenceDate")]
    public string ReferenceDate { get; set; }

}

反序列化实际上很短。示例 XML 可以使用以下代码进行反序列化:

using (var fs = new FileStream(@"c:\temp\xml1.xml", FileMode.Open))
{
    var xmls = new XmlSerializer(typeof(Conciliation));
    var xmlStructure = ((Conciliation)xmls.Deserialize(fs));
    xmlStructure.Dump();
}

解析后的值如下所示:

制作一个反序列化字符串输入的小方法,并在您的BuscarConciliacaoDiaCliente() 中使用它。

例如:

private Conciliation deserializeXml(string xmlContent)
{
    using (var fs = (TextReader)new StringReader(xmlContent))
    {
        var xmls = new XmlSerializer(typeof(Conciliation));
        var conciliation = ((Conciliation)xmls.Deserialize(fs));
        return conciliation;
    }
}

resposta.Content.ReadAsStringAsync().Result的内容作为xmlContent传递。

我不知道你的详细逻辑,但IMO你的函数可以写成如下:

public string BuscarConciliacaoDiaCliente()
{
    using (BDBONZAY bd = new BDBONZAY())
    {
        try
        {
            using (HttpClient requisicao = new HttpClient())
            {
                var resposta = requisicao.GetAsync("https://gabriel.free.beeceptor.com/bonzay").Result;
                
                if (resposta.StatusCode == HttpStatusCode.OK)
                {
                    //var xml = new XmlDocument();
                    //xml.LoadXml(resposta);

                    bd.BeginTransaction();
                    
                    Conciliation result = deserializeXml(resposta);

                    //XmlSerializer serializer = new XmlSerializer(typeof(Conciliation));
                    //using (TextReader reader = new StringReader(resposta))
                    //{
                    //  Conciliation result = (Conciliation)serializer.Deserialize(reader);
                    //}

                    bd.CommitTransaction();
                }
            }
        }
        catch (Exception ex)
        {
            bd.RollbackTransaction();
            throw;
        }
    //}
    return "";
}

【讨论】:

  • 我很高兴,答案有帮助! :)
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2012-06-20
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
相关资源
最近更新 更多