Convert JSON array to a c# object collection - c#

I've a JSON like below,
[
{
"document":
{
"createdDate":1476996267864,
"processedDate":1476996267864,
"taxYear":"2015",
"type":"user_document"
}
},
{
"document":
{
"createdDate":1476998303463,
"processedDate":0,
"taxYear":"2015",
"type":"user_document"
}
}
]
I need to convert it into a c# object. My object type is as below-
public class UserDocument
{
[JsonProperty(PropertyName = "type")]
public string type { get; set; }
[JsonProperty(PropertyName = "taxYear")]
public string taxYear { get; set; }
[JsonProperty(PropertyName = "createdDate")]
public string createdDate { get; set; }
[JsonProperty(PropertyName = "processedDate")]
public string processedDate { get; set; }
}
I'm using below code to deserialize the json but all UserDocument properties are null
var test = JsonConvert.DeserializeObject<List<UserDocument>>(jsonString);
Why am I getting all UserDocument properties are null, what's wrong here? I'm not getting any error.
Also can you suggest a good example in getting CouchBase queryresult into a .net object.

Seems your json is not in correct format. If I say your json is like
[
"document":
{
"createdDate":1476996267864,
"processedDate":1476996267864,
"taxYear":"2015",
"type":"user_document"
},
"document":
{
"createdDate":1476998303463,
"processedDate":0,
"taxYear":"2015",
"type":"user_document"
}
]
Then create a model like
public class Document
{
public UserDocument document {get;set;}
}
and change your UserDocument model's createdDate and processedDate properties as double because its like that in your json
public class UserDocument
{
[JsonProperty(PropertyName = "type")]
public string type { get; set; }
[JsonProperty(PropertyName = "taxYear")]
public string taxYear { get; set; }
[JsonProperty(PropertyName = "createdDate")]
public double createdDate { get; set; }
[JsonProperty(PropertyName = "processedDate")]
public double processedDate { get; set; }
}
and then deserialize
var test = JsonConvert.DeserializeObject<List<Document>>(jsonString);

Something like this (using Newtonsoft.Json.Linq):
var documents = JArray.Parse(json).Select(t => t["document"].ToObject<UserDocument>());

Related

How to display JSON data (nested) in C#

I am fetching an API that returns a JSON response like this:
{
"id": 161635,
"rev": 1,
"fields": {
"System.Url": "http://google.com",
"System.Type": "Bug",
"System.State": "New",
"System.AssignedTo": {
"displayName": "John Doe"
}
}
}
I want to display the id and everything inside fields.
This is my model:
public class WorkItemDetail {
public int id { get; set; }
public Dictionary<string, object> fields {get;set;}
}
Here is the problem, I can display the id and everything in fields except for some reason, I can't show displayName
Here is what I doing:
#WorkItemDetailResponse.id
#WorkItemDetailResponse.fields["System.WorkItemType"];
#WorkItemDetailResponse.fields["System.State"];
#WorkItemDetailResponse.fields["System.AssignedTo"];
#WorkItemDetailResponse.fields["System.AssignedTo"]["displayName"]; <!-- does not work -->
#code{
WorkItemDetailResponse = JsonConvert.DeserializeObject<WorkItemDetail>(ResponseBody);
}
I am new to C# so I don't know why this line is not working
#WorkItemDetailResponse.fields["System.AssignedTo"]["displayName"]
Create your DTO structure as follows:
public class Fields
{
[JsonProperty("System.Url")]
public string SystemUrl { get; set; }
[JsonProperty("System.Type")]
public string SystemType { get; set; }
[JsonProperty("System.State")]
public string SystemState { get; set; }
[JsonProperty("System.AssignedTo")]
public SystemAssignedTo SystemAssignedTo { get; set; }
}
public class WorkItemDetail
{
public int id { get; set; }
public int rev { get; set; }
public Fields fields { get; set; }
}
public class SystemAssignedTo
{
public string displayName { get; set; }
}
here's fiddle: https://dotnetfiddle.net/F9Wppv
another way - using dynamic variable: https://dotnetfiddle.net/Goh7YY
You need to cast the object value to a JObject
((JObject)JsonConvert.DeserializeObject<WorkItemDetail>(json).fields["System.AssignedTo"])["displayName"]
JSON.Net will create a JObject if the property type is object and the value is a JSON object.
db<>fiddle

deserialize API response with different json value in the result

I'm querying an external service and wanted to deserialize the response into a customer object but the issue is response for each customer may be different. some customer may have Sales entity in the response and few may have Marketing.
The json property for sales entity is SalesId and for marketing is MarketingId. Can you advise whether the model I use to store result is correct or any improvement ? If so, how would I deserialize the response without knowing the correct json property ?
For Customer 66666
{
"customerId": "66666",
"customerName": "test1234",
"dependentEntity": [
{
"SalesId": "3433434",
"SalesPersonName": "343434",
"SaleSource": "StorePurchase"
}
]
}
For Customer 5555
{
"customerId": "55555",
"customerName": "test2",
"dependentEntity": [
{
"MarketingId": "3433434",
"MarketingAppName": "343434",
"MarketingSource": "Online"
}
]
}
Here is the Model I'm thinking but not sure the correct one
public class Customer
{
public string customerId { get; set; }
public string customerName { get; set; }
public IList<T> dependentList { get; set; }
}
public class Dependent
{
[JsonProperty("Id")]
public string Id { get; set; }
public string Name { get; set; }
public string Source { get; set; }
}
You could probably try something like the following one:
public class DependentEntity
{
[JsonProperty("SalesId")]
public string SalesId { get; set; }
[JsonProperty("SalesPersonName")]
public string SalesPersonName { get; set; }
[JsonProperty("SaleSource")]
public string SaleSource { get; set; }
[JsonProperty("MarketingId")]
public string MarketingId { get; set; }
[JsonProperty("MarketingAppName")]
public string MarketingAppName { get; set; }
[JsonProperty("MarketingSource")]
public string MarketingSource { get; set; }
}
public class Customer
{
[JsonProperty("customerId")]
public string CustomerId { get; set; }
[JsonProperty("customerName")]
public string CustomerName { get; set; }
[JsonProperty("dependentEntity")]
public IList<DependentEntity> DependentEntity { get; set; }
}
We have a type for DependentEntity that has both the attributes of Marketing and Sales object. After parsing your input, you could create a logic (checking the attributes) based on which you could check if a DependentEntity is a Marketing or a Sales object.
The above classes was generated using, jsonutils.
If we can assume that the dependentEntity contains only a single type of objects then you can use json.net's schema to perform branching based on the matching schema.
So, lets suppose you have these dependent entity definitions:
public class DependentMarket
{
public string MarketingId { get; set; }
public string MarketingAppName { get; set; }
public string MarketingSource { get; set; }
}
public class DependentSales
{
public string SalesId { get; set; }
public string SalesPersonName { get; set; }
[JsonProperty("SaleSource")]
public string SalesSource { get; set; }
}
...
Then you can use these classes to generate json schemas dynamically:
private static JSchema marketSchema;
private static JSchema salesSchema;
//...
var generator = new JSchemaGenerator();
marketSchema = generator.Generate(typeof(DependentMarket));
salesSchema = generator.Generate(typeof(DependentSales));
And finally you can do the branching like this:
var json = "...";
var semiParsedJson = JObject.Parse(json);
JArray dependentEntities = (JArray)semiParsedJson["dependentEntity"];
JObject probeEntity = (JObject)dependentEntities.First();
if (probeEntity.IsValid(marketSchema))
{
var marketEntities = dependentEntities.ToObject<List<DependentMarket>>();
...
}
else if (probeEntity.IsValid(salesSchema))
{
var salesEntities = dependentEntities.ToObject<List<DependentSales>>();
...
}
else if ...
else
{
throw new NotSupportedException("The provided json format is not supported");
}

Deserialize JSON using specific properties

I'm trying to deserialize JSON without declaring every property in C#. Here is a cut-down extract of the JSON:
{
"resourceType": "export",
"type": "search",
"total": 50,
"timestamp": "2020-08-02T18:26:06.747+00:00",
"entry": [
{
"url": "test.com/123",
"resource": {
"resourceType": "Slot",
"id": [
"123"
],
"schedule": {
"reference": {
"value": "testvalue"
}
},
"status": "free",
"start": "2020-08-03T08:30+01:00",
"end": "2020-08-03T09:00+01:00"
}
}
]
}
I want to get the values out of entry → resource, id and start.
Any suggestions on the best way to do this?
I've made very good experiences with json2sharp. You can enter your JSON data there and it will generate the classes you need to deserialize the JSON data for you.
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
public class Root
{
public string resourceType { get; set; }
public string type { get; set; }
public int total { get; set; }
public DateTime timestamp { get; set; }
public List<Entry> entry { get; set; }
}
The next step is to choose a framework which will help you to deserialize. Something like Newtonsoft JSON.
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
If you want to get the data without declaring classes, you can use Json.Net's LINQ-to-JSON API (JToken, JObject, etc.). You can use the SelectToken method with a JsonPath expression to get what you are looking for in a couple of lines. Note that .. is the recursive descent operator.
JObject obj = JObject.Parse(json);
List<string> ids = obj.SelectToken("..resource.id").ToObject<List<string>>();
DateTimeOffset start = obj.SelectToken("..resource.start").ToObject<DateTimeOffset>();
Working demo here: https://dotnetfiddle.net/jhBzl4
If it turns out there are actually multiple entries and you want to get the id and start values for all of them, you can use a query like this:
JObject obj = JObject.Parse(json);
var items = obj["entry"]
.Children<JObject>()
.Select(o => new
{
ids = o.SelectToken("resource.id").ToObject<List<string>>(),
start = o.SelectToken("resource.start").ToObject<DateTimeOffset>()
})
.ToList();
Demo: https://dotnetfiddle.net/Qe8NB7
I am not sure why you don't deserialize the lot (even if it's minimally populated) since you have to do the inner classes anyway.
Here is how you could bypass some of the classes (1) by digging into the JObjects
Given
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
You could call
var results = JObject.Parse(input)["entry"]
.Select(x => x.ToObject<Entry>());

Parse JSON to object

I am working with box api, and trying to parse json object to a class.
This is the json:
{
"type":"folder",
"id":"0",
"sequence_id":null,
"etag":null,
"name":"All Files",
"created_at":null,
"modified_at":null,
"description":"",
"size":9049537,
"path_collection":
{
"total_count":0,"entries":[]
},
"created_by":
{
"type":"user","id":"","name":"","login":""
},
"modified_by":
{
"type":"user",
"id":"111",
"name":"a a",
"login":"a#gmail.com"
},
"trashed_at":null,
"purged_at":null,
"content_created_at":null,
"content_modified_at":null,
"owned_by":
{
"type":"user",
"id":"111",
"name":"a a",
"login":"a#gmail.com"
},
"shared_link":null,
"folder_upload_email":null,
"parent":null,
"item_status":"active",
"item_collection":
{
"total_count":4,
"entries":
[
{
"type":"file",
"id":"22887167395",
"sequence_id":"0",
"etag":"0",
"sha1":"883c99863eefc0f46b3d34915cc4d97a6008fabf",
"name":"13.ppt"
},
{
"type":"file",
"id":"22887169687",
"sequence_id":"0",
"etag":"0",
"sha1":"a345fd68b1c90a3678a3e746e0e5343693d8a022",
"name":"6.docx"
}
],
"offset":0,
"limit":100,
"order":
[
{
"by":"type",
"direction":"ASC"
},
{
"by":"name",
"direction":"ASC"
}
]
}
}
Basically, this is the root folder (in that case) that contains two files:
13.ppt
6.docx
I created a class:
[JsonObject(MemberSerialization.OptIn)]
public class BoxFile
{
[JsonProperty(PropertyName = "type")]
public string Type { get; internal set; }
[JsonProperty(PropertyName = "id")]
public string Id { get; internal set; }
[JsonProperty(PropertyName = "sequence_id")]
public string SequenceId { get; internal set; }
[JsonProperty(PropertyName = "etag")]
public string Etag { get; internal set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; internal set; }
[JsonProperty(PropertyName = "created_at")]
public string CreatedAt { get; internal set; }
[JsonProperty(PropertyName = "modified_at")]
public string ModifiedAt { get; internal set; }
[JsonProperty(PropertyName = "description")]
public string Description { get; internal set; }
[JsonProperty(PropertyName = "size")]
public long Size { get; internal set; }
[JsonProperty(PropertyName = "item_collection")]
public IEnumerable<BoxFile> ItemCollection { get; internal set; }
}
But the "item_collection" part is not working.. it gives me an error..
How do I get a list of subfiles inside "item_collection"?
I use it by:
private T ParseJson<T>(string json) where T : class, new()
{
JObject jobject = JObject.Parse(json);
return JsonConvert.DeserializeObject<T>(jobject.ToString());
}
And:
BoxFile parsed = ParseJson<BoxFile>(json);
You are getting an error because your class structure does not match your JSON. Specifically, in the JSON, the item_collection property is an object, not a list. That JSON object has two properties, total_count and entries, the latter of which contains the actual list of files. To handle this, you need to define another class:
public class ItemCollection
{
[JsonProperty(PropertyName = "entries")]
public IEnumerable<BoxFile> Entries { get; internal set; }
}
and then change the ItemCollection property in your BoxFile class to use this new class:
[JsonProperty(PropertyName = "item_collection")]
public ItemCollection ItemCollection { get; internal set; }
You can then access the list of files like this:
BoxFile parsed = ParseJson<BoxFile>(json);
foreach (BoxFile file in parsed.ItemCollection.Entries)
{
Console.WriteLine(file.Name);
}
Here is a working demo: https://dotnetfiddle.net/DB9Coc
As an aside, you can simplify your ParseJson method to one line. There is no need to parse the JSON to an JObject, turn it back into JSON and then parse it again.
private T ParseJson<T>(string json) where T : class, new()
{
return JsonConvert.DeserializeObject<T>(json);
}

Deserialize to Object with a List

Im trying to parse an JSON response string to my class objects.. I can't figure this out and i need some help with this.
I use the json.net reference but i cant't find what i'm looking for :(
my json:
{
"#companyName": "Company Name",
"#version": "1.0",
"#generatedDate": "3/1/10 2:10 PM",
"application": [
{
"#name": "Application #1 name",
"#apiKey": "1234",
"#createdDate": "2010-03-01",
"#platform": "Platform name"
},
{
"#name": "Application #1 name",
"#apiKey": "1234",
"#createdDate": "2010-03-01",
"#platform": "Platform name"
}
]
}
my root class for the json is:
public class RootObject
{
[JsonProperty]
public string companyName { get; set; }
[JsonProperty]
public string version { get; set; }
[JsonProperty]
public string generatedDate { get; set; }
[JsonProperty]
public List<Application> application { get; set; }
}
my sub class (list of applications):
public class Application
{
[JsonProperty]
public string name { get; set; }
[JsonProperty]
public string apiKey { get; set; }
[JsonProperty]
public string createdDate { get; set; }
[JsonProperty]
public string platform { get; set; }
}
To parse it i have the following code now:
JObject obj = JObject.Parse(e.Result);
applications = new RootObject
{
companyName = (string) obj["companyName"],
version = (string) obj["version"],
generatedDate = (string) obj["generatedDate"],
application = ???????? (how to make a list here?)
}
Thanks in advance!
Change your class definitions as follows
public class RootObject
{
[JsonProperty("#companyName")]
public string companyName { get; set; }
[JsonProperty("#version")]
public string version { get; set; }
[JsonProperty("#generatedDate")]
public string generatedDate { get; set; }
public List<Application> application { get; set; }
}
public class Application
{
[JsonProperty("#name")]
public string name { get; set; }
[JsonProperty("#apiKey")]
public string apiKey { get; set; }
[JsonProperty("#createdDate")]
public string createdDate { get; set; }
[JsonProperty("#platform")]
public string platform { get; set; }
}
and deserialize
var rootObj = JsonConvert.DeserializeObject<RootObject>(myjson);
A project I work on occasionally uses Json.Net. It's a wonderful library.
I would use the JsonConvert.DeserializeObject method instead.
In your case I would try something like this:
var result = JsonConvert.DeserializeObject<RootObject>(yourJsonString);
That should take care of it.
Can you try the following code and report back any issues:
RootObject applications = JsonConvert.DeserializeObject<RootObject>(e.Result);

Categories

Resources