Why is deserialized object fields are coming as null when data exists?

I have a json object that I need to deserialize, I'm using Json.NET to make these operations.

when it's a simple object, its quite easy to do it, but I cant figure out how to deserialize this string

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

Now the code I have so far:

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

}

Sum of the values of the deserialized object are null, even though the jsonString definitelly has data.

How should I proceed here?

3 answers

  • answered 2019-03-13 17:33 Jackson

    You need to create a contructor for the ApiLink class so you can do the following:

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

    The constructor would look something like the following:

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

  • answered 2019-03-13 17:43 Jlalonde

    The way your json is structured:

    {
     "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":""
                }]
            }
        ]
    }
    

    This is telling us that you have an object, with an array of objects called Aspsp-list.

    If this is what you intended great. We need to create an object similar to this

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

    To deserialize to this simply: JsonConvert.Deserialize<RootJsonObject>(/*your json string*/ value);

    If you wanted to only work with the array, you would need to deserialize purely to an IEnumerable/Array But you would also need to change your json to just be an array, not an object wrapping an array.

  • answered 2019-03-14 11:35 Erick Santander

    I managed to make it work now, my problem wasn't exactly that I couldn't deserialize because of data types or structure (at least not completely, comment that said that the structure was wrong was partly right).

    So, this is how I solved the problem:

    -> Created an empty costructor on the AspspListResponseResource class, so that the method JsonConvert.DeserializeObject<T>(jsonString) could create an instance of the object, I thought of this since the only constructor took a string, and so there was no other contructor for JsonConvert to use.

    -> Put the field names of with help of [JsonProperty(PropertyName = "")], but this still gave me the deserialized object as null, or with some null fields.

    -> commented the fields Transaction and FundsConfirmations of the ApiLink class, these fields were in the documentation of the Web API so I put them in, but looking at the json string I recieve, it look like they aren't being used, so I just commented them

    and after these changes the code now works flawlessly:

    The code:

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