C# 反序列化C时为Null对象#

C# 反序列化C时为Null对象#,c#,.net,xml,C#,.net,Xml,我正试图将XML请求转换为C#对象,但我做不到。我尝试了几种StackOverFlow解决方案,但都不起作用。有人知道会是什么吗?因为对象上的头是空的,所以请求中有更多的标记,但我正在逐步组装它 我不知道这是否有区别,但在Header类中,我将XmlRoot标记更改为XmlElement,并在没有反序列化的情况下继续 我有以下文件和函数 文件: Função: public string BuscarConciliacaoDiaCliente() { using (BDB

我正试图将XML请求转换为C#对象,但我做不到。我尝试了几种StackOverFlow解决方案,但都不起作用。有人知道会是什么吗?因为对象上的头是空的,所以请求中有更多的标记,但我正在逐步组装它

我不知道这是否有区别,但在Header类中,我将XmlRoot标记更改为XmlElement,并在没有反序列化的情况下继续

我有以下文件和函数

文件:

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:


20151013145131
123456789
2.
020202
20150920
0
1.
0
0
0
0
12345678912356
1117737
20150818155931
20150818125935
4.
1.
3635000017434024
20150920034340
20
19.602000
20150921
109863
1.
840.72
840.72
0
1.
24111
0123456
2.
2.
3.
1.
2.
1.
1.
1.
1.
1.

序列化不起作用,因为类成员是私有的,而xml序列化只对公共成员起作用。您需要做的第一个更改是将描述xml结构的成员设置为公共:

From:
类成员可以具有五种声明的可访问性中的任意一种,并且默认为私有声明的可访问性

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();
}
解析的值如下所示:

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

例如:

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;
    }
}
作为
xmlContent
传递
resposta.content.ReadAsStringAsync().Result的内容

我不知道您的详细逻辑,但在我看来,您的函数可以编写如下:

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

序列化不起作用,因为类成员是私有的,而xml序列化只对公共成员起作用。您需要做的第一个更改是将描述xml结构的成员设置为公共:

From:
类成员可以具有五种声明的可访问性中的任意一种,并且默认为私有声明的可访问性

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();
}
解析的值如下所示:

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

例如:

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;
    }
}
作为
xmlContent
传递
resposta.content.ReadAsStringAsync().Result的内容

我不知道您的详细逻辑,但在我看来,您的函数可以编写如下:

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

还可以添加尝试反序列化的XML结构(resposta.content.ReadAsStringAsync().Result的内容)
?为什么要用LINQ(XmlDocument.LoadXml)分析两次响应一旦使用XmlSerializer,是否故意跳过标题?XML文档缺少
?根元素
未关闭?奇怪的是,当我编辑文章时,我可以看到XML已正确关闭。在本地修复XML文档后,使用LINQ加载和解析结构可以正常工作:
var XML=XDLoad(@“c:\temp\xml1.xml”);
。使用
XmlSerializer
它也应该可以工作。我忘了放标题()。我将把它放在api中,然后再试一次。如果要测试,我已经更新了api。是的,标记调解已关闭。我尝试放置标头,但仍然出现相同的错误,这不正确。您还可以添加尝试反序列化的XML结构(resposta.content.ReadAsStringAsync()的内容).Result
?为什么要对响应进行两次解析?一次是使用LINQ(XmlDocument.LoadXml)一旦使用XmlSerializer,是否故意跳过标题?XML文档缺少
?根元素
未关闭?奇怪的是,当我编辑文章时,我可以看到XML已正确关闭。在本地修复XML文档后,使用LINQ加载和解析结构可以正常工作:
var XML=XDLoad(@“c:\temp\xml1.xml”);
。使用
XmlSerializer
它也应该可以工作。我忘了放标题()。我将把它放在api中,然后再试一次。如果你想测试,我已经更新了api。是的,标记已关闭。我尝试放置标题,但仍然出现相同的错误,但没有成功。谢谢,这对我有效!!!:我很高兴,答案对我有帮助!:)谢谢,这对我有效!!!:我很高兴,答案对我有帮助!:)