Deserialize JSON subdocument - c#

I'm calling the JIRA Rest API to recieve a list of Worklog Objects.
The JSON I recieve looks like.
{
"startAt": 0,
"maxResults": 1,
"total": 1,
"worklogs": [
{
"self": "http://www.example.com/jira/rest/api/2/issue/10010/worklog/10000",
"author": {
"self": "http://www.example.com/jira/rest/api/2/user?username=fred",
"name": "fred",
"displayName": "Fred F. User",
"active": false
},
"updateAuthor": {
"self": "http://www.example.com/jira/rest/api/2/user?username=fred",
"name": "fred",
"displayName": "Fred F. User",
"active": false
},
"comment": "I did some work here.",
"visibility": {
"type": "group",
"value": "jira-developers"
},
"started": "2015-08-25T07:43:10.086+0000",
"timeSpent": "3h 20m",
"timeSpentSeconds": 12000,
"id": "100028"
}
]
}
As I said, I want to put it in a list.
var json = client.MakeRequest("", password, user);
List<Worklog> myList = JsonConvert.DeserializeObject<List<Worklog>>(json);
It doesn't work, because of
"startAt": 0,
"maxResults": 1,
"total": 1,
How can I make the deserializer ignore those properties?
Thanks for your help!

Either create a "RootObject" class that does contain the properties:
public class RootObject
{
public int startAt { get; set; }
public int maxResults { get; set; }
public int total { get; set; }
public List<Worklog> worklogs { get; set; }
}
And deserialize into that:
var rootObject = JsonConvert.DeserializeObject<RootObject>(json);
// access rootObject.worklogs
Or step into the parsed JSON and deserialize from there:
JObject o = JObject.Parse(json);
JToken worklogsJson = o.SelectToken("worklogs");
var worklogs = worklogsJson.ToObject<List<Worklog>>();

Related

Deserialize Dynamic JSON Object

I am using a thirdparty API and the Json response that I receive back is as below.
Usually, using something like
Newtonsoft.Json.JsonConvert.DeserializeObject<MyModel>(response);
I can easily create a .Net model. However, I am struggling on how to formulate the below. I've tried KeyValuePairs, strings, modifying the actual Json but cannot seem to get any joy.
What am I missing?
{
"1": [
{
"qty": 1,
"discount": "flat",
"price": 71.68
}
],
"2": [
{
"qty": 1,
"discount": "flat",
"price": 62.75
}
],
"3": [
{
"qty": 1,
"discount": "flat",
"price": 77.28
}
],
"4": [
{
"qty": 1,
"discount": "flat",
"price": 82.88
}
],
"5": [
{
"qty": 1,
"discount": "flat",
"price": 67.84
}
]
}
Now, what is throwing me is that the numbers(1,2,3,4,5) are Identifiers so will not stay constant and could change each time you receive the response.
I think Newtonsoft can do this for you.
string json = #"{
'Email': 'james#example.com',
'Active': true,
'CreatedDate': '2013-01-20T00:00:00Z',
'Roles': [
'User',
'Admin'
]
}";
var jsonReturn = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>( json );
Console.WriteLine( jsonReturn.Email );
Based on this link:
https://www.newtonsoft.com/json/help/html/DeserializeObject.htm
This is the most basic explanation. Use a foreach to iterate over de nodes
Using #Liam's suggestion of JObject I have come up with this working solution
public class MyObject
{
public int id { get; set; }
public int qty { get; set; }
public string discount { get; set; }
public decimal price { get; set; }
}
and then after retrieving the JSON response...
var jsonObj = JsonConvert.DeserializeObject<JObject>(response);
List<MyObject> myObjects = new List<MyObject>();
foreach (var item in jsonObj.AsJEnumerable())
{
var csp = JsonConvert.DeserializeObject<List<MyObject>>(item.First.ToString());
csp.ForEach(a => { a.product_id = Convert.ToInt32(item.Path); });
myObjects.AddRange(csp);
}

Using ASP.NET Core 3, how do I make the json response not serialize a complex type?

I have this model:
public class Product
{
public Product()
{
this.Supplier = new Supplier();
}
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public int SupplierId { get; set; }
public ProductStatus Status { get; set; }
public Supplier Supplier { get; set; }
}
and another model:
public class Supplier
{
public Supplier()
{
this.Products = new List<Product>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public ICollection<Product> Products { get; set; }
}
Whenever I try to send json response using the product model, I get this kind of result:
{
"id": 1,
"name": "HP-ENVY 15",
"price": 800,
"supplierId": 0,
"status": 0,
"supplier": {
"id": 1,
"name": "HP",
"address": "Mckinley",
"products": []
}
}
And when trying to send a response using Supplier model:
{
"id": 1,
"name": "HP",
"address": "Mckinley",
"products": [
{
"id": 1,
"name": "HP-ENVY 15",
"price": 800,
"supplierId": 0,
"status": 0,
"supplier": {
"id": 0,
"name": null,
"address": null,
"products": []
}
},
{
"id": 12,
"name": "HP-PAVILION 14",
"price": 550,
"supplierId": 0,
"status": 0,
"supplier": {
"id": 0,
"name": null,
"address": null,
"products": []
}
},
{
"id": 13,
"name": "HP-ENVY 17",
"price": 1200.7,
"supplierId": 0,
"status": 0,
"supplier": {
"id": 0,
"name": null,
"address": null,
"products": []
}
},
{
"id": 14,
"name": "Printer xxx-2020",
"price": 300.5,
"supplierId": 0,
"status": 0,
"supplier": {
"id": 0,
"name": null,
"address": null,
"products": []
}
},
{
"id": 15,
"name": "Compaq Presario",
"price": 500.8,
"supplierId": 0,
"status": 0,
"supplier": {
"id": 0,
"name": null,
"address": null,
"products": []
}
}
]
}
Both responses tries to serialize the complext object inside them, is it possible to:
1.) When sending the json response for the Product model, It would only display Products and its Supplier only(the products property of that supplier would not be inlcluded)
2.) When sending the json response for the Supplier model, it would only display the Supplier and its products only(the supplier property for each product would not be inlcuded)
Are there json options that I need to configure on my middleware in order to achieve this? or should I create DTOs/classes where the Supplier complex object being referenced inside the Product model has no property of its product and vice-versa for the Supplier model(it has no products property).
Note: I'm aware that it's best to use viewmodel/dtos for json response, but in my example let's just say that both Product and Model are not domain classes but rather viewmodels, as my main problem is how do I prevent json from preventing serializing the object property.
JSON.net has the MaxDepth property for deserealizing up to a certain point.
Beware though that this will help you up to a point. It will not identify same object cyclic dependency, it will just stop at the second level of deserialization.
For the opposite thing (serialization) you can use json.net limit maxdepth when serializing to extend the JsonTextWriter

How can I use regex to extract child node from JSON structure?

Hi I try to get json data inside of the json. But my class is Employee my service creates json as com.myteam.rbffiyatlama2.Employee this prefix can be changeable so I have to write a solution to get an exact part of the json Like below but my below code is not working. I will send my node name to a method Getjsonobject(Employee emp) or Getjsonobject(Customer cust) or Getjsonobject(Student student) etc.
My Json:
{
"type": "SUCCESS",
"msg": "Container RBFFiyatlama2_1.0.1 successfully called.",
"result": {"execution-results": {
"results": [
{
"value": 2,
"key": ""
},
{
"value": {"com.myteam.rbffiyatlama2.Employee": {
"salary": 2400,
"age": 35,
"cofactor": 0.2
}},
"key": "t1"
},
{
"value": {"com.myteam.rbffiyatlama2.Employee": {
"salary": 4800,
"age": 35,
"cofactor": 0.2
}},
"key": "t2"
}
],
"facts": [
{
"value": {"org.drools.core.common.DefaultFactHandle": {"external-form": "0:50:1980606587:1980606587:100:DEFAULT:NON_TRAIT:com.myteam.rbffiyatlama2.Employee"}},
"key": "t1"
},
{
"value": {"org.drools.core.common.DefaultFactHandle": {"external-form": "0:51:2052360932:2052360932:99:DEFAULT:NON_TRAIT:com.myteam.rbffiyatlama2.Employee"}},
"key": "t2"
}
]
}}
}
class Program
{
static void Main(string[] args)
{
var employee1 = new Employee() { age = 35, cofactor = 0.2, salary = 2000 };
var employee2 = new Employee() { age = 35, cofactor = 0.2, salary = 4000 };
var list = new List<Employee>();
list.Add(employee1);
list.Add(employee2);
var uri = new Uri("http://localhost:8080/kie-server/services/rest/server/containers/instances/RBFFiyatlama2_1.0.1");
var kieclient = new KieRequestWrapper<Employee>(uri, "kieserver", "#test2018", MethodType.POST, "application/json").Add(list).Run();
Console.Write(kieclient.Content);
var match = Regex.Match(kieclient.Content, #"(?*.Employee{*})");
var result= MyParser.Parse(match, typeof(Employee)); //Desired
Console.Read();
}
}
public class Employee
{
public int age { get; set; }
public double cofactor { get; set; }
public int salary { get; set; }
}
You don't want to use XPath to get the data you need, you want to deserialize the the JSON string into an object and then get the data you need. There are many JSON serialization libraries out there, the most common one, AFAIK, is JSON.NET. You can look at how deserialization works here: https://www.newtonsoft.com/json/help/html/DeserializeObject.htm
Example:
public class Account
{
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList<string> Roles { get; set; }
}
string json = #"{
'Email': 'james#example.com',
'Active': true,
'CreatedDate': '2013-01-20T00:00:00Z',
'Roles': [
'User',
'Admin'
]
}";
Account account = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine(account.Email);
// james#example.com

Cannot convert json to object

Hello i've got this error Message
"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ClassLibraryMifosX.ViewModels.Rootobject2' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\nTo fix this error either change the JSON to a JS
my deserialize code :
Rootobject Rsc = JsonConvert.DeserializeObject<Rootobject>(json);
my class with json object description:
public class Rootobject
{
public List<Class1> Property1 { get; set; }
}
public class Class1
{
public int entityId { get; set; }
public string entityAccountNo { get; set; }
public string entityExternalId { get; set; }
public string entityName { get; set; }
public string entityType { get; set; }
public int parentId { get; set; }
public string parentName { get; set; }
public string entityMobileNo { get; set; }
public Entitystatus entityStatus { get; set; }
}
public class Entitystatus
{
public int id { get; set; }
public string code { get; set; }
public string value { get; set; }
}
my json :
[
{
"entityId": 1,
"entityAccountNo": "000000001",
"entityExternalId": "100001-241563",
"entityName": "Smith W R",
"entityType": "CLIENT",
"parentId": 1,
"parentName": "Head Office",
"entityMobileNo": "254728000000",
"entityStatus": {
"id": 300,
"code": "clientStatusType.active",
"value": "Active"
}
},
{
"entityId": 310,
"entityAccountNo": "000000310",
"entityName": "John Smith",
"entityType": "CLIENT",
"parentId": 14,
"parentName": "TestOffice1",
"entityStatus": {
"id": 300,
"code": "clientStatusType.active",
"value": "Active"
}
},
{
"entityId": 422,
"entityAccountNo": "000000422",
"entityExternalId": "smith1",
"entityName": "Smith Jones",
"entityType": "CLIENT",
"parentId": 11,
"parentName": "Barquisimeto",
"entityMobileNo": "88989898",
"entityStatus": {
"id": 300,
"code": "clientStatusType.active",
"value": "Active"
}
},
{
"entityId": 774,
"entityAccountNo": "000000774",
"entityName": "John AAA Smith",
"entityType": "CLIENT",
"parentId": 1,
"parentName": "Head Office",
"entityStatus": {
"id": 300,
"code": "clientStatusType.active",
"value": "Active"
}
},
{
"entityId": 1789,
"entityAccountNo": "Head Office000001789",
"entityExternalId": "547222",
"entityName": "Kaitlin Smith",
"entityType": "CLIENT",
"parentId": 1,
"parentName": "Head Office",
"entityStatus": {
"id": 300,
"code": "clientStatusType.active",
"value": "Active"
}
}
]
what i have been done wrongly ? Thanks
There is no root object into your Json data so just deserialize it as a collection of Class1 like below:
var collection = JsonConvert.DeserializeObject<List<Class1>>(json);
Don't forget that VS can create for you a class that can be used to deserailize your Json data. You don't need to write yourself the definition of Class1. Just go to menu => Edit > Paste Special > Paste JSON as classes
The first and last character of your JSON is a square bracket [ ] rather than a curly bracket { }. This means that it is an array, not an object. In order to parse it, you need to deserialize it into an array of Class1 objects:
Class1[] Rsc = JsonConvert.DeserializeObject<Class1[]>(json);
If you wanted to use a Rootobject object instead, you could then use it like so:
Rootobject root = new RootObject();
root.Property1 = new List<Class1>(Rsc);

How to Serialise Dictionary<int, object> to JSON, but Ignore Key

I have the following class property
public Dictionary<int, Hotel> Hotels { get; set; }
When I serialize to JSON the dictionary key is being serialized as follows:
{
"results": {
"id": "d875e165-4705-459e-8532-fca2ae811ae0",
"arrival_date": "2019-02-16",
"departure_date": "2019-02-17",
"expires": "2019-01-17T17:11:23.2941604+00:00",
"hotels": {
"9036": {
"hotel_id": 9036,
"name": "Beach View Hotel",
"address": null,
"star_rating": 0,
"review_score": 0,
"phone_number": null,
"website_url": null,
"email_address": null,
"channels": [
{
"id": 0,
"name": "Channel Name 0",
"offers": []
}
]
},
"9049": {
"hotel_id": 9049,
"name": "City House Hotel",
"address": null,
"star_rating": 0,
"review_score": 0,
"phone_number": null,
"website_url": null,
"email_address": null,
"channels": [
{
"id": 0,
"name": "Channel Name 0",
"offers": []
}
]
},
"9107": {
"hotel_id": 9107,
"name": "Park Hotel",
"address": null,
"star_rating": 0,
"review_score": 0,
"phone_number": null,
"website_url": null,
"email_address": null,
"channels": [
{
"id": 1,
"name": "Channel Name 1",
"offers": []
}
]
}
},
"errors": []
}
}
Is it possible to remove somehow, maybe by class property attribute?
"9036":
So the desired JSON becomes
"hotels": { "hotel_id": 9036, "name": "My Hotel Name",
The format "hotels": { "hotel_id": 9036, "name": "My Hotel Name", ... },.. is not valid, but you can make it an array "hotels": [ { "hotel_id": 9036, "name": "My Hotel Name", ... } ].
You can do so by marking your Dictionary with JsonIgnore and exposing a Collection of Hotels which contains Values from the Dictionary of Hotels.
For example,
var hotel = new Results
{
id= "d875e165-4705-459e-8532-fca2ae811ae0",
HotelDictionary = new Dictionary<int,Hotels> {
[2323]=new Hotels{Id=2323,Name="Sample1"},
[1323]=new Hotels{Id=1323,Name="Sample2"},
}
};
var jsonString = JsonConvert.SerializeObject(hotel,Newtonsoft.Json.Formatting.Indented);
Where Results and Hotels is defined as (please note i have ignored other properties to focus on dictionary, but you can add them in for your final solution).
public class Results
{
public string id { get; set; }
[JsonIgnore]
public Dictionary<int,Hotels> HotelDictionary { get; set; }
[JsonProperty("hotels")]
public IEnumerable<Hotels> Hotels => HotelDictionary.Select(x=>x.Value);
}
public class Hotels
{
[JsonProperty("hotel_id")]
public int Id{get;set;}
[JsonProperty("name")]
public string Name{get;set;}
}
Output
{
"id": "d875e165-4705-459e-8532-fca2ae811ae0",
"hotels": [
{
"hotel_id": 2323,
"name": "Sample1"
},
{
"hotel_id": 1323,
"name": "Sample2"
}
]
}
You cannot do that because this JSON structure is not valid:
"hotels": { "hotel_id": 9036, "name": "My Hotel Name", ... }, { ... }
You can, however, select only the values and serialize that:
hotels.Values;
To get this:
"hotels": [ { "hotel_id": 9036, "name": "My Hotel Name", ... }, { ... } ]
Given that that's part of a class, you'll need a new model:
public class SomeName
{
public List<Hotel> Hotels { get; set; }
}
var someName = new SomeName
{
Hotels = hotels.Values.ToList();
};
I think the problem may be that you need to add hotel_id as a property on the Hotel object.
Depending on where your data is coming from, this is probably a good idea anyways, not just in this case.

Categories

Resources