skip to Main Content

Good day,

I am new to JSON handling and have encountered an issue I can’t resolve, despite checking the Newtonsoft documentation. I hope you can help me out.

I have a JSON file downloaded locally (@"F:BankStamm.json") that looks like this:

{
  "totalSize" : 1212,
  "validOn" : "2024-06-10",
  "readTime" : "2024-06-08T16:30:26.058475214+02:00",
  "entries" : [ {
    "entryType" : "BankMaster",
    "iid" : 100,
    "validOn" : "2024-06-10",
    "sicIid" : "001008",
    "headQuarters" : 100,
    "iidType" : "HEADQUARTERS",
    "bankOrInstitutionName" : "Schweizerische Nationalbank",
    "streetName" : "Börsenstrasse",
    "buildingNumber" : "15",
    "postCode" : "8022",
    "townName" : "Zürich",
    "country" : "CH",
    "bic" : "SNBZCHZZXXX",
    "sicParticipation" : true,
    "rtgsCustomerPaymentsChf" : true,
    "ipCustomerPaymentsChf" : false,
    "euroSicParticipation" : true,
    "lsvBddChfParticipation" : true,
    "lsvBddEurParticipation" : false
  }, {
    "entryType" : "BankMaster",
    "iid" : 110,
    "validOn" : "2024-06-10",
    "sicIid" : "001100",
    "headQuarters" : 100,
    "iidType" : "MAIN_BRANCH",
    "bankOrInstitutionName" : "Schweizerische Nationalbank",
    "streetName" : "Bundesplatz",
    "buildingNumber" : "1",
    "postCode" : "3003",
    "townName" : "Bern",
    "country" : "CH",
    "bic" : "SNBZCHZZXXX",
    "sicParticipation" : true,
    "rtgsCustomerPaymentsChf" : true,
    "ipCustomerPaymentsChf" : false,
    "euroSicParticipation" : true,
    "lsvBddChfParticipation" : true,
    "lsvBddEurParticipation" : false
  }, {
    "entryType" : "BankMaster",
    "iid" : 115,
    "validOn" : "2024-06-10",
    "sicIid" : "001158",
    "headQuarters" : 100,
    "iidType" : "MAIN_BRANCH",
    "bankOrInstitutionName" : "Schweizerische Nationalbank",
    "streetName" : "Bundesverw. / Bundesplatz",
    "buildingNumber" : "1",
    "postCode" : "3003",
    "townName" : "Bern",
    "country" : "CH",
    "bic" : "SNBZCHZZXXX",
    "sicParticipation" : true,
    "rtgsCustomerPaymentsChf" : true,
    "ipCustomerPaymentsChf" : false,
    "euroSicParticipation" : true,
    "lsvBddChfParticipation" : true,
    "lsvBddEurParticipation" : false
  }, {
// etc ... (The file is shortened for ease of reading - there are 1212 entries in total)

I’ve created a class ClsBankMasterRecordJson to map only a few attributes:

public sealed class ClsBankMasterRecordJson
{
    #region member variables

    string iid { get; set; }
    string bic { get; set; } 
    string bankOrInstitutionName { get; set; }
    string streetName { get; set; }
    string buildingNumber { get; set; }
    string postCode { get; set; }
    string townName { get; set; }
    string country { get; set; }

    #endregion
}

Now that I’ve laid the fundamentals, I’d like to read my JSON file and put only the attributes that are part of my ‘ClsBankMasterRecordJson’ class as long as it finds something. My intention was to output a List.

For the sake of achieving this, I have created the following method:

public void readBankStammNew()
{
    using (StreamReader r = new StreamReader(@"F:BankStamm.json"))
    {
        string json = r.ReadToEnd();
        List<ClsBankMasterRecordJson> items = JsonConvert.DeserializeObject<List<ClsBankMasterRecordJson>>(json);
    }
}

Unfortunately, I’ve come up against the following error, which I can’t understand : "Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type System.Collections.Generic.List`1[Finapp2013.ClsBankMasterRecordJson]’ because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly."

I understand that the error indicates a mismatch between the expected JSON structure and the provided data, but I don’t see the issue. Could you help me resolve this?

Thank you in advance for your help and your time!

2

Answers


  1. Here is one way to achieve what you are after.

    First, add [JsonProperty] attributes to your ClsBankMasterRecordJson class, like this:

    public class ClsBankMasterRecordJson
    {
        [JsonProperty("iid")]
        long iid { get; set; }
    
        [JsonProperty("bic")]
        string bic { get; set; }
    
        // (etc)
    }
    

    Note that the iid property here is a long (not a string) because it’s a numeric type in the JSON file.

    Then parse the JSON you have read from the file to a dynamic type:

    dynamic parsedJson = JObject.Parse(json);
    

    Get the entries property as a JArray:

    var array = (JArray)parsedJson.entries;
    

    Then convert element-wise to your custom type:

    var list = array.ToObject<List<ClsBankMasterRecordJson>>();
    

    Caveat: this is not necessarily the cleanest or most performant approach (but it might suffice depending upon your use case).

    Alternative method (possibly cleaner)

    As an alternative to the dynamic parsing approach, you could instead add the following class:

    public class FullJson
    {
        [JsonProperty("entries")]
        List<ClsBankMasterRecordJson> entries { get; set; }
    }
    

    Then you could simply do this:

    var fullJson = JsonConvert.DeserializeObject<FullJson>(json);
    

    And the entries property of your fullJson variable would be the list you need. (You will still need to add the [JsonProperty] attributes to your ClsBankMasterRecordJson class.)

    Login or Signup to reply.
  2. add "public" to properties.
    can read full json to class, or just list of nodes.

    in addition, you can adjust types of properties: iid, buildingNumber can be int…

    also, i try to show you in this example that property dont have to match json field. you can make match by Document Attribute [JsonProperty("JSONFIELDNAME")] as I made example of property ID (matching iid json token)

    
    void Main()
    {
        string json = "{"totalSize":1212,"validOn":"2024-06-10","readTime":"2024-06-08T16:30:26.058475214+02:00","entries":[{"entryType":"BankMaster","iid":100,"validOn":"2024-06-10","sicIid":"001008","headQuarters":100,"iidType":"HEADQUARTERS","bankOrInstitutionName":"Schweizerische Nationalbank","streetName":"Börsenstrasse","buildingNumber":"15","postCode":"8022","townName":"Zürich","country":"CH","bic":"SNBZCHZZXXX","sicParticipation":true,"rtgsCustomerPaymentsChf":true,"ipCustomerPaymentsChf":false,"euroSicParticipation":true,"lsvBddChfParticipation":true,"lsvBddEurParticipation":false},{"entryType":"BankMaster","iid":110,"validOn":"2024-06-10","sicIid":"001100","headQuarters":100,"iidType":"MAIN_BRANCH","bankOrInstitutionName":"Schweizerische Nationalbank","streetName":"Bundesplatz","buildingNumber":"1","postCode":"3003","townName":"Bern","country":"CH","bic":"SNBZCHZZXXX","sicParticipation":true,"rtgsCustomerPaymentsChf":true,"ipCustomerPaymentsChf":false,"euroSicParticipation":true,"lsvBddChfParticipation":true,"lsvBddEurParticipation":false},{"entryType":"BankMaster","iid":115,"validOn":"2024-06-10","sicIid":"001158","headQuarters":100,"iidType":"MAIN_BRANCH","bankOrInstitutionName":"Schweizerische Nationalbank","streetName":"Bundesverw. / Bundesplatz","buildingNumber":"1","postCode":"3003","townName":"Bern","country":"CH","bic":"SNBZCHZZXXX","sicParticipation":true,"rtgsCustomerPaymentsChf":true,"ipCustomerPaymentsChf":false,"euroSicParticipation":true,"lsvBddChfParticipation":true,"lsvBddEurParticipation":false}]}";
        //to read from file
        //string json = File.ReadAllText("path to file");
        var j = JToken.Parse(json).SelectToken("entries");
        Console.Write(JsonConvert.DeserializeObject<List<ClsBankMasterRecordJson>>(j.ToString()));
    }
    
    public sealed class ClsBankMasterRecordJson
    {
        #region member variables
        //add public othervise will not bind data
        [JsonProperty("iid")]
        public int  ID { get; set; }
        public string bic { get; set; }
        public string bankOrInstitutionName { get; set; }
        public string streetName { get; set; }
        public int buildingNumber { get; set; }
        public string postCode { get; set; }
        public string townName { get; set; }
        public string country { get; set; }
        #endregion
    }
    
    

    the result would be

    ID bic bankOrInstitutionName streetName buildingNumber postCode townName country
    100 SNBZCHZZXXX Schweizerische Nationalbank Börsenstrasse 15 8022 Zürich CH
    110 SNBZCHZZXXX Schweizerische Nationalbank Bundesplatz 1 3003 Bern CH
    115 SNBZCHZZXXX Schweizerische Nationalbank Bundesverw. / Bundesplatz 1 3003 Bern CH
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search