Using JSONconvert.Deserializeobject to Deserialize JSON to a C# Poco Class

Using JsonConvert.DeserializeObject to deserialize Json to a C# POCO class

Here is a working example.

Keypoints are:

  • Declaration of Accounts
  • Use of JsonProperty attribute

.

using (WebClient wc = new WebClient())
{
var json = wc.DownloadString("http://coderwall.com/mdeiters.json");
var user = JsonConvert.DeserializeObject<User>(json);
}

-

public class User
{
/// <summary>
/// A User's username. eg: "sergiotapia, mrkibbles, matumbo"
/// </summary>
[JsonProperty("username")]
public string Username { get; set; }

/// <summary>
/// A User's name. eg: "Sergio Tapia, John Cosack, Lucy McMillan"
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }

/// <summary>
/// A User's location. eh: "Bolivia, USA, France, Italy"
/// </summary>
[JsonProperty("location")]
public string Location { get; set; }

[JsonProperty("endorsements")]
public int Endorsements { get; set; } //Todo.

[JsonProperty("team")]
public string Team { get; set; } //Todo.

/// <summary>
/// A collection of the User's linked accounts.
/// </summary>
[JsonProperty("accounts")]
public Account Accounts { get; set; }

/// <summary>
/// A collection of the User's awarded badges.
/// </summary>
[JsonProperty("badges")]
public List<Badge> Badges { get; set; }
}

public class Account
{
public string github;
}

public class Badge
{
[JsonProperty("name")]
public string Name;
[JsonProperty("description")]
public string Description;
[JsonProperty("created")]
public string Created;
[JsonProperty("badge")]
public string BadgeUrl;
}

How can I deserialize JSON into this POCO class?

Here you go:

var root = JsonConvert.DeserializeObject<RootObject>(json);
var userItem = root.results.items
.Select(i => new UserItem
{
id = i.id,
name = i.name,
title = i.title
}).FirstOrDefault();

return userItem;

As you already know, you can't just convert the Item class into a UserItem, but you can build one. One thing to note here is that obviously if you only want to return one you'll have to just grab one. Here I've grabbed the first or default. The default would be null if the list were empty for example.

Deserializing JSON with Newtonsoft, using a specific class

Copy your JSON. Open Visual studio. Create new C# class file. Now Select below menu option:

Edit > Paste Special > Paste JSON as classes

This will create a class as below

public class Rootobject
{
public Datum[] data { get; set; }
}

public class Datum
{
public string type { get; set; }
public string id { get; set; }
}

Now change RootObject to jsonTask and deserialise as below

jsonTask test = JsonConvert.DeserializeObject<jsonTask>(strJSON);

How Can I deserialize a json into a structure?

Yet another solution could be to make use of the JsonSchema

First let's redefine your data model:

public abstract class Settings
{
[JsonProperty("id")]
public string Id { get; set; }

[JsonProperty("type")]
public string Type { get; set; }
}

public class SettingsV1 : Settings
{
[JsonProperty("content")]
public string Content { get; set; }
}

public class SettingsV2 : Settings
{
[JsonProperty("content")]
public Content Content { get; set; }
}

public class Content
{
[JsonProperty("id")]
public string Id { get; set; }

[JsonProperty("duration")]
public long Duration { get; set; }
}
  • Instead of having a middle man (ContentStructure) rather than you can have two separate Settings versions
  • The common fields are defined inside the abstract base class

Now, you can use these two versioned classes to define json schemas:

private static JSchema schemaV1;
private static JSchema schemaV2;

//...
var generator = new JSchemaGenerator();
schemaV1 = generator.Generate(typeof(SettingsV1));
schemaV2 = generator.Generate(typeof(SettingsV2));

Finally all you need to do is to do a preliminary check before calling the DeserializeObject with the proper type:

Settings settings = null;
var semiParsed = JObject.Parse(json);
if (semiParsed.IsValid(schemaV1))
{
settings = JsonConvert.DeserializeObject<SettingsV1>(json);
}
else if (semiParsed.IsValid(schemaV2))
{
settings = JsonConvert.DeserializeObject<SettingsV2>(json);
}
else
{
throw new NotSupportedException("The provided json format is not supported");
}

JsonConvert.DeserializeObject error while deserializing a string

You should be deserializing into the type, not an array of the type. It's a single object containing an array, but the root json is not an array.

var birdRecords = JsonConvert.DeserializeObject<birdDataSolutionVM>(data);

Convert JSON to C# POCO

JObject defines method Parse for this:

JObject json = JObject.Parse(str);

or try for a typed object try:

Foo json  = JsonConvert.DeserializeObject<Foo>(str)

Deserialize JSON to C# Classes

Your problem is twofold:

  1. You don't have a class defined at the root level. The class structure needs to match the entire JSON, you can't just deserialize from the middle.
  2. Whenever you have an object whose keys can change, you need to use a Dictionary<string, T>. A regular class won't work for that; neither will a List<T>.

Make your classes like this:

class RootObject
{
[JsonProperty("results")]
public Results Results { get; set; }
}

class Results
{
[JsonProperty("jobcodes")]
public Dictionary<string, JobCode> JobCodes { get; set; }
}

class JobCode
{
[JsonProperty("_status_code")]
public string StatusCode { get; set; }
[JsonProperty("_status_message")]
public string StatusMessage { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}

Then, deserialize like this:

RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);

Working demo here

Deserialize a list of lists

you have to create the whole class, not just an array part. try this

Data data=JsonConvert.DeserializeObject<Data>(jsonString )

or if you need just alarmRecords, you don't need D and PagedAlarms classes. try this code

var jsonParsed=JObject.Parse(json);

List<AlarmRecord> alarmRecords=jsonParsed["d"]["paged_alarms"]["alarm_records"].ToObject<List<AlarmRecord>>();

classes

    public partial class Data
{
[JsonProperty("d")]
public D D { get; set; }
}

public partial class D
{
[JsonProperty("__type")]
public string Type { get; set; }

[JsonProperty("account_id")]
public string AccountId { get; set; }

[JsonProperty("message")]
public object Message { get; set; }

[JsonProperty("paged_alarms")]
public PagedAlarms PagedAlarms { get; set; }
}

public partial class PagedAlarms
{
[JsonProperty("__type")]
public string Type { get; set; }

[JsonProperty("alarm_records")]
public List<AlarmRecord> AlarmRecords { get; set; }
}

public partial class AlarmRecord
{
[JsonProperty("__type")]
public string Type { get; set; }

[JsonProperty("alarm_record_details")]
public List<AlarmRecordDetail> AlarmRecordDetails { get; set; }

[JsonProperty("lat")]
public double Lat { get; set; }

[JsonProperty("lon")]
public double Lon { get; set; }

[JsonProperty("time")]
public string Time { get; set; }
}

public partial class AlarmRecordDetail
{
[JsonProperty("__type")]
public string Type { get; set; }

[JsonProperty("active")]
public bool Active { get; set; }

[JsonProperty("code")]
public string Code { get; set; }

[JsonProperty("color")]
public string Color { get; set; }

[JsonProperty("title")]
public string Title { get; set; }
}

How do I deserialize JSON where there is an array of ane/value properties along with a Location which has three values?

just change a type of a value property from string to object and add Location class

public class PropertyAttribute
{
public string name { get; set; }

private object _value;

public object value
{
get
{

if (_value as JObject !=null)
return ((JObject)_value).ToObject<Location>();
return _value?.ToString();
}

set { _value = value; }
}
}

public class Location
{
public int alt { get; set; }
public double lat { get; set; }
public double lon { get; set; }
}

how to use

var propertyChangeData = JsonConvert.DeserializeObject<CustomEventModel>(requestBody);

Location location = (Location) propertyChangeData.properties.Where(p => p.name=="Location").FirstOrDefault().value;

string DeviceSerialNumber = (string) propertyChangeData.properties.Where(p => p.name=="DeviceSerialNumber").FirstOrDefault().value;

Newtonsoft.Json.JsonSerializationException: C#

In your Root class, change the List<Data> data to Data data and then you can de-serialize your JSON string as required to your Root class:

using System;
using Newtonsoft.Json;

public class Program
{
public static void Main()
{
string jsonString = "{\"data\":{\"merchantRefNo\":\"foo\"," +
"\"responseText\":\"Approved\"," +
"\"status\":\"A\"," +
"\"txnDate\":\"20220321\"," +
"\"txnId\":\"000067\"," +
"\"txnTime\":\"1049\"," +
"\"txnType\":\"sale\"," +
"\"amt\":\"109\"}," +
"\"dataType\":\"trans\"}";

var result =JsonConvert.DeserializeObject<Root>(jsonString);
Console.WriteLine(result.dataType);
Console.WriteLine(result.data.merchantRefNo);
Console.WriteLine(result.data.status);
Console.WriteLine(result.data.txnId);
}
}

public class Data
{
public string merchantRefNo { get; set; }
public string responseText { get; set; }
public string status { get; set; }
public string txnDate { get; set; }
public string txnId { get; set; }
public string txnTime { get; set; }
public string txnType { get; set; }
public string amt { get; set; }
}

public class Root
{
public Data data { get; set; }
public string dataType { get; set; }
}

Output:

trans
foo
A
000067

You can find a working example here: https://dotnetfiddle.net/8Nsl9m



Related Topics



Leave a reply



Submit