Search code examples
c#jsonjson.net

Parse only some attributes of a JSON file in c# using the Newtonsoft Json.NET library


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!


Solution

  • 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