1

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> 
6
  • 1
    Can you also add the XML structure that you are trying to deserialize (the content of resposta.Content.ReadAsStringAsync().Result? Why are you parsing the response twice - once with LINQ (XmlDocument.LoadXml) and once with the XmlSerializer? Commented Jan 6, 2021 at 17:51
  • Is the header skipped on purpose? The XML document is missing <?xml version="1.0" ?>? The root element <Conciliation> is not closed? Commented Jan 6, 2021 at 17:57
  • Weird, when I edit the post I can see, that the XML is closed properly. After fixing the XML document locally, then loading and parsing the structure with LINQ works properly: var xml = XDocument.Load(@"c:\temp\xml1.xml");. With the XmlSerializerit should work also. Commented Jan 6, 2021 at 17:59
  • 1
    I forgot to put the header (<?xml version="1.0" ?>). I will put it in the api and try again. If you want to test I already updated the API. Yes, Tag Conciliation is closed Commented Jan 6, 2021 at 18:01
  • I tried putting the header and it continues with the same error, it doesn't convert Commented Jan 6, 2021 at 18:08

1 Answer 1

3

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 learn.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:\temp\xml1.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 ""; } 
Sign up to request clarification or add additional context in comments.

1 Comment

I am glad, that the answer helped! :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.