【问题标题】:Why is deserialized object fields are coming as null when data exists?当数据存在时,为什么反序列化的对象字段为空?
【发布时间】:2019-03-13 17:22:51
【问题描述】:

我有一个需要反序列化的 json 对象,我正在使用 Json.NET 进行这些操作。

当它是一个简单的对象时,它很容易做到,但我不知道如何反序列化这个字符串

json

{
    "aspsp-list":
    [
        {
            "id":"424250495054504C",
            "bic":"BBPIPTPL",
            "bank-code":"0010",
            "aspsp-cde":"BBPI",
            "name":"BANCO BPI, SA",
            "logoLocation":"../img/corporate/theBank.jpg",
            "api-list":[{
                "consents":["BBPI/v1/consents"],
                "payments":["BBPI/v1/payments"],
                "accounts":["BBPI/v1/accounts"],
                "funds-confirmations":["BBPI/v1/funds-confirmations"]
            }]
        },
        {
            "id":"544F54415054504C",
            "bic":"TOTAPTPL",
            "bank-code":"0018",
            "aspsp-cde":"BST",
            "name":"BANCO SANTANDER TOTTA, SA",
            "logoLocation":"../img/openBank.svc",
            "api-list":[{
                "consents":["BBPI/v1/consents"],
                "payments":["BBPI/v1/payments"],
                "accounts":["BBPI/v1/accounts"],
                "funds-confirmations":["BST/v1/funds-confirmations"]
            }]
        }
    ]
}

现在我的代码:

internal class AspspListResponseResource 
{
    // Report with the list of supported ASPSPs. Each ASPSP will include the list of available API endpoints and the logo.
    [JsonProperty(PropertyName = "aspsp-list")]
    public AspspList[] AspspList { get; set; }

    public AspspListResponseResource() { /* Empty constructor to create the object */ }

     public AspspListResponseResource(string jsonString)
     {
        //var alrr = JsonConvert.DeserializeObject<AspspListResponseResource>(jsonString);

        JObject jObject = JObject.Parse(jsonString);
        JToken jUser = jObject["aspsp-list"];

        // The root object here is coming with certain fields as null, such as 'aspsp-cde', 'bank-code' and 'api-list'
        AspspListResponseResource root = JsonConvert.DeserializeObject<AspspListResponseResource>(jsonString);                        
     }
}

internal class Aspsp
{
    // ASPSP Id
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; } = "";

    // Bank Identifier Code
    [JsonProperty(PropertyName = "bic")]
    public string Bic { get; set; } = "";

    // IBAN Bank Identifier
    [JsonProperty(PropertyName = "bank-code")]
    public string BankCode { get; set; } = "";

    // ASPSP Code to use in the endpoint
    [JsonProperty(PropertyName = "aspsp-cde")]
    public string AspspCde { get; set; } = "";

    // Institution name
    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; } = "";

    // Bank logo location
    [JsonProperty(PropertyName = "logoLocation")]
    public string LogoLocation { get; set; } = "";

    // Bank Supported API List
    [JsonProperty(PropertyName = "api-list")]
    public ApiLink[] ApiList { get; set; }
}

internal class ApiLink
{
    // Consents Link List
    [JsonProperty(PropertyName = "consents")]
    public string[] Consents { get; set; } = { "" };

    // Payments Link List
    [JsonProperty(PropertyName = "payments")]
    public string[] Payments { get; set; } = { "" };

    // Accounts Link List
    [JsonProperty(PropertyName = "accounts")]
    public string[] Accounts { get; set; } = { "" };

    // Balances Link List
    [JsonProperty(PropertyName = "balances")]
    public string[] Balances { get; set; } = { "" };

    // Transaction Link List
    [JsonProperty(PropertyName = "transaction")]
    public string[] Transaction { get; set; } = { "" };

    // Funds-Confirmations Link List
    [JsonProperty(PropertyName = "funds-confirmations")]
    public string[] FundsConfirmations { get; set; } = { "" };

}

反序列化对象的值总和为空,即使 jsonString 肯定有数据。

我应该如何继续?

【问题讨论】:

  • Deserialize JSON with C#的可能重复
  • 生成模型的一种简单方法是 Paste JSON as Classes 现在您的模型与您的 json 不匹配。
  • @Jlalonde 为什么这个问题是重复的,我认为我正在寻求帮助的 json 更复杂。
  • 您应该能够将 Json 直接反序列化到对象中。类似于var object = JsonConvert.DeserializeObject&lt;List&lt;aspasp&gt;&gt;(jsonString); 的东西(替换&lt;List&lt;aspasp&gt;&gt; 以匹配你想要的类)
  • 埃里克。几乎任何任意 Json 都可以使用 json.net 中的 JsonConvert 进行反序列化。如果说多态,我会同意。但最终我相信它是重复的。

标签: c# arrays json serialization json.net


【解决方案1】:

你的 json 的结构方式:

{
 "aspsp-list":
    [
        {
            "id":"123123123",
            "bic":"BBPIPTPL",
            "bank-code":"0010",
            "aspsp-cde":"BBPI",
            "name":"BANCO BPI, SA",
            "logoLocation":"../img/corporate/theBank.jpg",
            "api-list":[{
                "consents":"",
                "payments":"",
                "accounts":"",
                "funds-confirmations":""
            }]
        },
        {
            "id":"1434231231",
            "bic":"TOTAPTPL",
            "bank-code":"0018",
            "aspsp-cde":"BST",
            "name":"BANCO SANTANDER TOTTA, SA",
            "logoLocation":"../img/openBank.svc",
            "api-list":[{
                "consents":"",
                "payments":"",
                "accounts":"",
                "funds-confirmations":""
            }]
        }
    ]
}

这告诉我们您有一个对象,其中包含一个名为 Aspsp-list 的对象数组。

如果这是您的本意,那就太好了。 我们需要创建一个类似这样的对象

public class RootJsonObject {
    public IEnumerable<Aspsp> Aspsp-list {get; set;}
}

简单地反序列化为: JsonConvert.Deserialize&lt;RootJsonObject&gt;(/*your json string*/ value);

如果您只想使用数组,则需要完全反序列化为 IEnumerable/Array 但您还需要将 json 更改为数组,而不是包装数组的对象。

【讨论】:

  • 我按照你说的做了,并且在反序列化对象时设法不抛出异常。但它不可能是 IEnumerable,因为它给了我一个错误,说它必须是一个数组,问题是我在 AspspListResponseResource 类和字段名称中创建了一个构造函数(用 JsonProperty(PropertyName = "")),它覆盖了空的构造函数,所以在创建了一个空的构造函数之后,我现在可以反序列化了。但是该对象现在有一些字段为空,但它不应该。我将更新问题,如果可以,请帮助我。
  • 我会查找 Json Convert。你可以让这变得更容易。
【解决方案2】:

我现在设法让它工作,我的问题不完全是因为数据类型或结构而无法反序列化(至少不完全是,说结构错误的评论部分正确)。

所以,这就是我解决问题的方法:

-> 在AspspListResponseResource类上创建了一个空的构造函数,这样JsonConvert.DeserializeObject&lt;T&gt;(jsonString)的方法就可以创建一个对象的实例,我想到了这个,因为唯一的构造函数取了一个string,所以没有供JsonConvert 使用的其他构造函数。

-> 在[JsonProperty(PropertyName = "")] 的帮助下放置字段名称,但这仍然给了我反序列化的objectnull,或者带有一些空字段。

-> 注释了ApiLink 类的TransactionFundsConfirmations 字段,这些字段在Web API 的文档中,所以我把它们放进去,但是看看我收到的json 字符串,它看起来像他们没有被使用,所以我只是评论了他们

在这些更改之后,代码现在可以完美运行:

代码:

internal class AspspListResponseResource 
{
    // Report with the list of supported ASPSPs. Each ASPSP will include the list of available API endpoints and the logo.
    [JsonProperty(PropertyName = "aspsp-list")]
    public Aspsp[] AspspList { get; set; }

    public AspspListResponseResource() { /* Empty constructor to create the object */ }

     public AspspListResponseResource(string jsonString)
     {
        AspspListResponseResource root = JsonConvert.DeserializeObject<AspspListResponseResource>(jsonString);
        this.AspspList = root.AspspList;
     }
}

internal class Aspsp 
{
    // ASPSP Id
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; } = "";

    // Bank Identifier Code
    [JsonProperty(PropertyName = "bic")]
    public string Bic { get; set; } = "";

    // IBAN Bank Identifier
    [JsonProperty(PropertyName = "bank-code")]
    public string BankCode { get; set; } = "";

    // ASPSP Code to use in the endpoint
    [JsonProperty(PropertyName = "aspsp-cde")]
    public string AspspCde { get; set; } = "";

    // Institution name
    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; } = "";

    // Bank logo location
    [JsonProperty(PropertyName = "logoLocation")]
    public string LogoLocation { get; set; } = "";

    // Bank Supported API List
    [JsonProperty(PropertyName = "api-list")]
    public ApiLink[] ApiList { get; set; }
}

internal class ApiLink 
{
    // Consents Link List
    [JsonProperty(PropertyName = "consents")]
    public string[] Consents { get; set; } = { "" };

    // Payments Link List
    [JsonProperty(PropertyName = "payments")]
    public string[] Payments { get; set; } = { "" };

    // Accounts Link List
    [JsonProperty(PropertyName = "accounts")]
    public string[] Accounts { get; set; } = { "" };

    // Balances Link List
    [JsonProperty(PropertyName = "balances")]
    public string[] Balances { get; set; } = { "" };

    //// Transaction Link List
    //[JsonProperty(PropertyName = "transaction")]
    //public string[] Transaction { get; set; } = { "" };
    //
    //// Funds-Confirmations Link List
    //[JsonProperty(PropertyName = "funds-confirmations")]
    //public string[] FundsConfirmations { get; set; } = { "" };

}

【讨论】:

    【解决方案3】:

    您需要为 ApiLink 类创建一个构造函数,以便执行以下操作:

    var apiListRaw = new ApiLink(value["api-list"][0] as JObject);
    

    构造函数如下所示:

    public ApiLink(JObject json)
    {
        Consensts = (string[])json["consents"];
        ...
    }
    

    【讨论】:

    • @ErickSantander 我刚刚意识到 api-list json 有点奇怪。它似乎是一个列表,但只有一个元素,可能涉及更多循环,你有一个非空 api 列表的例子吗?还刚刚编辑了我的答案,使其更符合我所看到的。
    • 我注意到,它说它不能转换为字符串 [],我没有非空的 api-link,我可以手动添加元素到它
    • 答案实际上取决于填充的 api-link 的样子。截至目前,您似乎只能在 api-link 列表中的每个元素获得一次同意/付款。在这种情况下,向构造函数发送一个 JArray 并对其进行循环以填充数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    相关资源
    最近更新 更多