-1

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?

Erick Santander
  • 311
  • 3
  • 17
  • Possible duplicate of [Deserialize JSON with C#](https://stackoverflow.com/questions/7895105/deserialize-json-with-c-sharp) – Jlalonde Mar 13 '19 at 17:39
  • 2
    An easy way to generate a model is to [Paste JSON as Classes](https://www.c-sharpcorner.com/article/how-to-paste-json-as-classes-or-xml-as-classes-in-visual-stu/) right now your model doesn't match your json. – JSteward Mar 13 '19 at 17:48
  • @Jlalonde Why is the question duplicate, I think the json I'm asking help with is more complex. – Erick Santander Mar 13 '19 at 18:00
  • You should be able to just deserialize the Json straight into the object. Something along the lines of `var object = JsonConvert.DeserializeObject>(jsonString); ` (replace `>` to match the class you want) – Dortimer Mar 13 '19 at 18:04
  • Erick. Almost Any arbitrary Json can be deserialized using JsonConvert in json.net. I would agree if it was say polymorphic. But ultimately I believe it's a duplicate. – Jlalonde Mar 13 '19 at 19:28

3 Answers3

2

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.

Jlalonde
  • 483
  • 4
  • 13
  • I did as you said, and managed to not throw an exeption when deserializing the object. It couldn't be an IEnumerable though, as it gave me an error saying it had to be an array, the problem was that I was making a constructor on the AspspListResponseResource class and in the names of the fields (fixed with JsonProperty(PropertyName = "")), and it was overriting the empty constructor, so after creating an empty constructor I can now deserialize. but the object has some fields as null now were it shouldn't. I'm going to update the question, please help me if you can. – Erick Santander Mar 14 '19 at 10:28
  • I would look up Json Convert. You can make this far easier. – Jlalonde Mar 14 '19 at 11:38
1

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

}
Erick Santander
  • 311
  • 3
  • 17
0

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"];
    ...
}
Jackson
  • 87
  • 12
  • @ErickSantander I just realised the api-list json is a bit weird. It seems to be a list but there's only one element, there might be more loops involved, do you have an example with a non-empty api-list? Also just edited my answer to be more in line with what I'm seeing. – Jackson Mar 13 '19 at 17:37
  • I noticed, It says that it cant convert to string[], I don't have a non empty api-link, I could just hand-add elements to it though – Erick Santander Mar 13 '19 at 17:40
  • The answer really depends on what a populated api-link would look like. As of now, it looks like you'll only have one consent/payment per element in the api-link list. In that case, send the constructor a JArray and loop over it to populate the arrays. – Jackson Mar 13 '19 at 17:45