Deserializing Json to .Net Object Using Newtonsoft (Or Linq to Json Maybe)

Deserializing JSON to .NET object using Newtonsoft (or LINQ to JSON maybe?)

If you just need to get a few items from the JSON object, I would use Json.NET's LINQ to JSON JObject class. For example:

JToken token = JObject.Parse(stringFullOfJson);

int page = (int)token.SelectToken("page");
int totalPages = (int)token.SelectToken("total_pages");

I like this approach because you don't need to fully deserialize the JSON object. This comes in handy with APIs that can sometimes surprise you with missing object properties, like Twitter.

Documentation: Serializing and Deserializing JSON with Json.NET and LINQ to JSON with Json.NET

Why does Newtonsoft JsonConvert not deserialize Json array fields?

The reason why you could not deserialize it directly is because your json and your data model has a mismatch.

"details":"[{\"field_id\":\"1142488407\",\"response\":\"256\",\"field_type\":\"text\"},..]"
  • In this case your details data type is string
  • So, you can NOT parse it directly as a collection of objects

if your json would look like this:

"details":[{\"field_id\":\"1142488407\",\"response\":\"256\",\"field_type\":\"text\"},..]
  • the the data type of the details field would be a collection

So, the very reason why did your second approach worked is because you have first deserialized the details then you deserialized the json array.

Deserialize JSON into any object

I have acheived something similar using Newtonsoft

Your route should take the body in as a generic object and it can then be deserialized into any object you'd like:

/*Using this method, the controller will automatically handle
validating proper Json format*/
[HttpPost]
public async Task<IActionResult> Post([FromBody] object Body)
{

/*here you will send the generic object to a service which will deserialize.
the object into an expected model.*/

customService.HandlePost(Body);
}

Now create an object with any expected fields you would get from the body. (Json2csharp.com is extremely useful!)

public class MessageBody    
{
public string Token { get; set; }
public string Name { get; set; }

}

Inside your service you can handle the object like this:

using Newtonsoft.Json
using Models.MessageBody

public class customService()
{

public void HandlePost(object body)
{

var DeserializedBody = JsonConvert.DeserializeObject<MessageBody>(body);

//Any Values that were not assigned will be null in the deserialized object
if(DeserializedBody.Name !== null)
{
//do something
}

}

}

This is obviously a very bare bones implementation, error handling will be important to catch any invalid data. Instead of using one object and null fields to get the data you need, I would recommend adding a "subject" route variable (string) that you can use to determine which object to deserialize the body into.

post *api/MessageBody/{Subject}

Newtonsoft JSON Deserialize Dynamically

Have you looked into using JsonLinq and JObject.Parse()? You can then using something like the following:

string Data = "{\"t\":\"1339886\",\"a\":true,\"data\":[],\"Type\":[['Ants','Biz','Tro']]}";
JObject J = JObject.Parse(Data);
string[] Types = J["Type"][0].ToObject<string[]>();

Note: I didn't test this against your data structure.

Deserializing Json to list of objects in C# with Newtonsoft

You problem is reading the "text" object.
From you sample, it contains key/value pairs of string type both.
There is no reason to use ICollection there, but only Dictionary<string, string>

public class Options
{
public Dictionary<string, string> text { get; set; }
public List<string> cascade { get; set; }
public string val { get; set; }
}

Update:
Since your sample JSON does not include data about the cascade member (only an empty array), it might be safe declaring it as a list of objects List<object>.

Deserialize a json object with multiple nested objects /lists using JsonConvert

you have only getters in your classes. you need setters to assign values from json to c# objects

List<Parameter> Parameters = JsonConvert.DeserializeObject<ParamList>(json).Parameters;

classes

public class ParamList
{
public List<Parameter> Parameters { get; set; }
}

public class Parameter
{
public Info Info { get; set; }
public List<IntOption> IntOptions { get; set; }
public List<BubbleList> BubbleList { get; set; }
}

public class BubbleList
{
public int Position { get; set; }
public List<SubBubbleList> SubBubbleList { get; set; }
}

public class Info
{
public int Id { get; set; }
public string No { get; set; }
}

public class IntOption
{
public int Value { get; set; }
public string ValInfo { get; set; }
}

public class SubBubbleList
{
public int Value { get; set; }
public string Message { get; set; }
}

but if for some reasons you still need readonly you can change ALL your read only classes by moving json property name using this template

public class ParamList
{
[JsonProperty("Parameters")]
private List<Param> _param = new List<Param>();

public IReadOnlyCollection<Param> Param
{
get => _param.AsReadOnly();
}
}


Related Topics



Leave a reply



Submit