Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
146 views
in Technique[技术] by (71.8m points)

.net - Null object when deserializing C#

I'm trying to convert an XML request to a C # object, but I can't. I tried several StackOverFlow solutions, but none worked. Does anyone know what it could be? Because the Header on the object is null, well in the request there are more tags, but I'm assembling it gradually as it goes well.

I don't know if it makes a difference, but in the Header class I changed the XmlRoot tag to XmlElement and continued without deserializing

I have the following file and function

File:

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; }

  }
}

Fun??o:

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The serialization does not work because your class members are private and the xml serialization works only with public members. First change you need to make is to make your members, that describe the xml structure, public:

From docs.microsoft.com: Class 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; }

}

The deserialization is actually pretty short. The example XML can be deserialized with the following code:

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

The parsed values looks like this:

enter image description here

Make a small method that deserializes a string input and use it in your BuscarConciliacaoDiaCliente().

For example:

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;
    }
}

Pass as xmlContent the content of resposta.Content.ReadAsStringAsync().Result.

I don't know your logic in detail, but IMO your function could be written as follows:

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 "";
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...