how to convert json to list c# - c#

How to convert json to the class in C #
json in the database is similarly stored and is not interchangeable
[rules][0][id]:1,
[rules][0][field]:1,
[valid]:true,
[IsActive]:true
public class FilterRule
{
public bool IsActive { get; set; }
public string Field { get; set; }
public string Id { get; set; }
public List<FilterRule> Rules { get; set; }
public string Value { get; set; }
}

You can use the following :
var model = JsonConvert.DeserializeObject<List<FilterRule>>(yourJson);
Assuming that FilterRule is the list of objects you want.
Hope it helps!

Related

Json.NET Deserialize Property Without Deserializing Parent Object Above It

I am trying to take this JSON:
{
"title":"string",
"description":"string",
"date":"2021-04-19T01:05:38.000Z",
"image":"url",
"images":[
"url1",
"url2"
],
"attributes":{
"phonebrand":"x",
"phonecarrier":"y",
"forsaleby":"z",
"price":12345,
"location":"daLocation",
"type":"OFFERED"
},
"url":"url to listing"
}
And convert it into this C# Object:
public class Listing {
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("date")]
public DateTime? Date { get; set; }
[JsonProperty("image")]
public string Image { get; set; }
[JsonProperty("images")]
public string[] Images { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("price")]
public decimal Price { get; set; }
[JsonProperty("locationId")]
public int LocationId { get; set; }
[JsonProperty("categoryId")]
public int CategoryId { get; set; }
[JsonProperty("sortByName")]
public string SortByName { get; set; }
[JsonProperty("q")]
public string Q { get; set; }
[JsonProperty("location")]
public string Location { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("forsaleby")]
public string ForSaleBy { get; set; }
[JsonProperty("fulfillment")]
public string Fulfillment { get; set; }
[JsonProperty("payment")]
public string Payment { get; set; }
[JsonProperty("phonebrand")]
public string? PhoneBrand { get; set; }
[JsonProperty("phonecarrier")]
public string? PhoneCarrier { get; set; }
}
My problem is, I'm trying to deserialize properties like price and phonebrand but those properties are under an object in the JSON. So when I try to deserialize them like this, those properties can't be found and are set as null. How can I deserialize those properties without changing my C# Class to include an Attributes class? I want to do this because I think that it is a cleaner/better design compared the JSON I'm taking in.
I suggest two approaches that are very explicit and easy to follow for the next developer looking at the code.
Two classes
creating a intermediate dto class that is used for deserialisation and then creating the business logic object from that intermediate object.
var withAttributes = Deserialise<ListingDto>();
var flatObject = new Listing(withAttributes);
One class
You could provide accessors at the top level which dip into the subclasses.
public class Listing
{
public AttributesDto Attributes {get; set}
...
public string Url => Attributes.Url; // Maybe '?.Url'
}

JSON Deserializer returning NULL Values

I am trying to consume a REST API via a C# Console Application and I've got as far as getting the webservice to return the JSON file, with the format:
{"status":200,"result":{"postcode":"SW1W0DT","quality":1,"eastings":528813,"northings":178953,"country":"England","nhs_ha":"London","longitude":-0.145828,"latitude":51.494853,"european_electoral_region":"London","primary_care_trust":"Westminster","region":"London","lsoa":"Westminster 023E","msoa":"Westminster 023","incode":"0DT","outcode":"SW1W","parliamentary_constituency":"Cities of London and Westminster","admin_district":"Westminster","parish":"Westminster, unparished area","admin_county":null,"admin_ward":"Warwick","ccg":"NHS Central London (Westminster)","nuts":"Westminster","codes":{"admin_district":"E09000033","admin_county":"E99999999","admin_ward":"E05000647","parish":"E43000236","parliamentary_constituency":"E14000639","ccg":"E38000031","nuts":"UKI32"}}}
I have created a class AddressInfo which is as follows:
public class AddressInfo {
public string postcode { get; set; }
public int quality { get; set; }
public int eastings { get; set; }
public int northings { get; set; }
public string country { get; set; }
public string nhs_ha { get; set; }
public string admin_county { get; set; }
public string admin_district { get; set; }
public string admin_ward { get; set; }
public double longitude { get; set; }
public double latitude { get; set; }
public string parliamentary_constituency { get; set; }
public string european_electoral_region { get; set; }
public string primary_care_trust { get; set; }
public string region { get; set; }
public string parish { get; set; }
public string lsoa { get; set; }
public string msoa { get; set; }
public string ccg { get; set; }
public string nuts { get; set; }
public object codes { get; set; }
}
The code to call the API and get the values is:
string strJSON = string.Empty;
strJSON = rClient.makeRequest();
Console.Write(strJSON);
AddressInfo AI = new AddressInfo();
AI = Newtonsoft.Json.JsonConvert.DeserializeObject<AddressInfo>(strJSON);
However, when I debug, AI is returning the values as "NULL".
Thanks
Notice that your JSON has a nested structure. The AddressInfo is contained within its result property, it isn't at the top level.
Your actual class structure to deserialize the entire JSON response should look something like this (I've called the class JsonResponse but you can name it whatever you want):
class JsonResponse{
public int status { get; set; }
public AddressInfo result { get; set; }
}
Then deserialize it like this:
JsonResponse res = JsonConvert.DeserializeObject<JsonResponse>(strJSON);
AddressInfo addressInfo = res.result;
You're missing the fact that you need an outer class that has the properties int status and AdressInfo result.
You don't need to create a separate class to deserialize the entire response, this can be done dynamically to achieve desired result:
var source = "(your JSON");
dynamic data = JObject.Parse(source);
var d = JsonConvert.SerializeObject(data.result);
AddressInfo account = JsonConvert.DeserializeObject<AddressInfo>(d);
Your JSON is nested. The result is a nested object. That's why you are experiencing this issue.

Unable to deserialize JSON in c#

I am getting the below JSON in response from a REST API.
{
"data":{
"id":123,
"zoneid":"mydomain.com",
"parent_id":null,
"name":"jaz",
"content":"172.1 6.15.235",
"ttl":60,
"priority":null,
"type":"A",
"regions":[
"global"
],
"system_record":false,
"created_at":"2017-09-28T12:12:17Z",
"updated_at":"2017-09-28T12:12:17Z"
}
}
and trying to resolve using below code but that doesn't result in a correctly deserialized type.
var model = JsonConvert.DeserializeObject<ResponseModel>(response);
below is a class according the field I received in JSON response.
public class ResponseModel
{
public int id { get; set; }
public string zone_id { get; set; }
public int parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public int priority { get; set; }
public string type { get; set; }
public string[] regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
What is missing?
You're missing a wrapper class.
public class Wrapper
{
public ResponseModel data {get;set}
}
and then do:
var model = JsonConvert.DeserializeObject<Wrapper>(response).data;
to get the instance of your ResponseModel out the data property.
You can deduct this from your json:
{ "data":
{ "id":123, /*rest omitted */ }
}
The type that will receive this JSON needs to have a property named data. The suggested Wrapper class acts as that type.
According to json2csharp website, your model seems to be incorrect. Try this one :
public class ResponseModel
{
public int id { get; set; }
public string zoneid { get; set; }
public object parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public object priority { get; set; }
public string type { get; set; }
public List<string> regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
public class RootObject
{
public ResponseModel data { get; set; }
}
Here a cool trick you can do in Visual Studio 2015-2017 where it generates the the correct class if you just copy the JSON (ctrl + c).
You need to create a new class in visual studio and once inside the class go to Edit menu -> Paste special -> paste JSON As Classes.
Steps to generate json class
This will generate the C# object for that json for you and save you all the hassle :)
Your model does not match your response - it matches the data property. Simply wrap another object round it
public class ResponseData
{
public ResponseModel Data {get; set; {
}
and then
var model = JsonConvert.DeserializeObject<ResponseData>(response);

Deserializing Json string with C# using Newtonsoft.JSON

I have read some articles but didnt fix my problem , i have a problem with JSON string when deserialize, here the string
{"table":"sy_version","effected":2,"data":[{"mod_id":"CS","sub_mod":"sbm_sl.exe","version":"2015.11.07.1","upload_date ":"2015-11-10 11:34:13"},{"mod_id":"FA","sub_mod":"sbm_fa.exe","version":"2015.11.09","upload_date ":"2015-11-10 11:34:13"}]}
And this is my class
public class Datum
{
public string mod_id { get; set; }
public string sub_mod { get; set; }
public string version { get; set; }
public DateTime upload_date { get; set; }
}
public class sy_periode
{
public string table { get; set; }
public int effected { get; set; }
public IList<Datum> datas { get; set; }
}
public static void test(string str) {
// dynamic sy_periode = JsonConvert.DeserializeObject(str);
var sy_periode = JsonConvert.DeserializeObject<sy_periode>(str);
foreach (var data in sy_periode.datas)
{
Console.WriteLine(data.sub_mod);
}
}
When I executed, string table and effected have value, but datas is null, this is the error message
Object reference not set to an instance of an object.
It shouldn't be datas, it should have the same name as JSON object: data.
Here is the correct classes structure:
public class Datum
{
public string mod_id { get; set; }
public string sub_mod { get; set; }
public string version { get; set; }
public DateTime upload_date { get; set; }
}
public class sy_periode
{
public string table { get; set; }
public int effected { get; set; }
public IList<Datum> data { get; set; }
}
Also, note that in JSON your upload_date properties have an odd whitespace in the end: upload_date. It may be a typo. However, if it is an actual input and since C# member name cannot contain spaces, you can try to specify the name in order to serialize it:
[JsonProperty(PropertyName = "upload_date ")]
public DateTime upload_date { get; set; }
I am not quite sure that it will work, but I see no reasons of why it shouldn't.

Convert Json to two possible objects

I am currently receiving two different types of objects in Json format and I need to deserialize those Json into corresponding objects. However, my problem is that all of those objects are sent by the same channel which means when I receive an object but I don't know which type the object is. The two different types of objects is shown below. So my question is if there is a function that allows me to try to deserialize with one object type and if that fails, I use another one?
//Object1
public class OutputStream
{
public DateTime summaryId { get; set; }
public string total { get; set; }
public int userId { get; set; }
public string dataType { get; set; }
public SensorLocation location { get; set; }
public HeartRateActivityType activityType { get; set; }
}
//Object2
public class OutputStreamAMM
{
[DataMember]
public DateTime summaryId { get; set; }
[DataMember]
public string average { get; set; }
[DataMember]
public string max { get; set; }
[DataMember]
public string min { get; set; }
[DataMember]
public int userId { get; set; }
[DataMember]
public string dataType { get; set; }
[DataMember]
public SensorLocation location { get; set; }
[DataMember]
public HeartRateActivityType activityType { get; set; }
}
Any help is appreciated.
You could write a Json Schema for one of your models, and then validate your json document against the schema to see if it matches.
You can use Newtonsoft.Json for this.
var schema = JsonSchema.Parse(...);
var jtoken = JToken.Parse(jsonString);
if(jtoken.IsValid(schema))
{
var model = jtoken.ToObject<OutputStream>();
}
else
{
var model = jtoken.ToObject<OutputStreamAMM>();
}
A simpler way would be to check for a key field that only one of the classes is known to have:
var token = JToken.Parse(jsonString);
if(token.SelectToken("$.average") != null)
{
val model = token.ToObject<OutputStreamAMM>();
}
else
{
val model = token.ToObject<OutputStream>();
}
Can you just inspect the json for some type of key identifier?
For example if the json contains "average" you have OutputStreamAMM. If not you have OutputStream.
Write a function that has that logic.

Categories