Pramod Sawant
Pramod Sawant

Reputation: 29

Deserialize JSON string in to multiple C# objects

I have a JSON string in below format for which I want to deserialize it into C# List. But the record number "1","2","3" (it can be upto 1,2,3...n depends on the json response each time) in JSON restricting me to deserialize it into C# object using Newtonsoft.Json

{
"1":{
      "UID":"1",
      "LICENCENO":"licenseno",
      "NAME":"ABC"
    },
"2":{
      "UID":"2",
      "LICENCENO":"licenseno",
      "NAME":"PQR"
    },
"3":{
      "UID":"3",
      "LICENCENO":"licenseno",
      "NAME":"XYZ"      
    }
}

I am using below code for deserialization

var result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<DriverMaster>>(json);

I have DriverMaster class created as-

public class DriverMaster
{
    public string UID { get; set; }
    public string LICENCENO { get; set; }
    public string NAME { get; set; }
}

Deserialization line giving unhandled exception, I know I am doing it in wrong way, because DriverMaster json object cannot be extracted into c# directly without doing something to record number 1,2,3...n in c#. Can anyone please help me to sort it out? Thanks in advance.

Upvotes: 0

Views: 4913

Answers (4)

Anu Viswan
Anu Viswan

Reputation: 18155

You need to use

public class DriverMaster
{
    public string UID { get; set; }
    public string LICENCENO { get; set; }
    public string NAME { get; set; }
}

public class Root
{
    [JsonExtensionData]
    public IDictionary<string,JToken> Data {get;set;}
}

and

var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(json);

If you want to have result as List, you can parse the result as.

var list = new List<DriverMaster>();
foreach(KeyValuePair<string, JToken> token in result.Data)
{
    list.Add(token.Value.ToObject<DriverMaster>());
}

That would give you the desired result as

1 licenseno ABC 
2 licenseno PQR 
3 licenseno XYZ 

Upvotes: 1

mhand
mhand

Reputation: 1277

For these types of things I like to use the often overlooked feature of JToken.SelectTokens. This function allows you to select tokens within a json string and permits the use of wildcards.

Here's some code that will deserialize your sample by selecting past the 1,2,3...N in the json:

public static IEnumerable<DriverMaster> Deserialize(string json)
{
    return JToken.Parse(json).SelectTokens("*")
        .Select(jToken => jToken.ToObject<DriverMaster>());
}

The * basically says to select all tokens after the root, so it's selecting the values associated with 1, 2, 3.. etc... Here's another SO answer that shows a more complicated usage of the SelectTokens method.

Upvotes: 1

Svek
Svek

Reputation: 12858

Solution.
Change your code to use...

var result = JsonConvert.DeserializeObject<Dictionary<int, DriverMaster>>(json);

Explaination

The type is not the same... The List<DriverMaster>type will convert to JSON like so...

{
    "1":
    {
        "DriverMaster": {
            "UID":"1",
            "LICENCENO":"licenseno",
            "NAME":"ABC"
        }
    }
}

This doesn't match what you showed in your question...

The type that you are looking for is actually Dictionary<int, DriverMaster>, which is a key/value pair which will output a JSON string like so

{
    "1": { ... },
    "2": { ... },
    "3": { ... }
}

In order to fix that, you need to use the Dictionary<int, DriverMaster> type instead.

Upvotes: 2

Mark Feldman
Mark Feldman

Reputation: 16119

You were close:

var result = JsonConvert.DeserializeObject<Dictionary<string, DriverMaster>>(json)
    .Select(x => x.Value)
    .ToList();

Upvotes: 6

Related Questions