I am calling a RESTful service in C# and the result is similar to this:
{
"blabla":1,
"bbb":false,
"blabla2":{
"aaa":25,
"bbb":25,
"ccc":0
},
"I_want_child_list_from_this":{
"total":15226,
"max_score":1.0,
"I_want_this":[
{
"A":"val1",
"B":"val2",
"C":"val3"
},
{
"A":"val1",
"B":"val2",
"C":"val3"
}
...
]
"more_blabla": "fff"
...
}
I want to get the "I_want_this" part as a list of object or JObject
Is there something like
(JObject)responseString["I_want_child_list_from_this"]["I_want_this"]
more generically:
(JObject)responseString["sub"]["sub_sub"]
I am using Newtonsoft.Json
Thanks!
First off, I would create a class that represents the JSON structure returned from the service call. (http://json2csharp.com/ great utility for auto-generating classes from JSON)
Second, if you are not using Newtonsoft.Json library, I would recommending grabbing that library.
Lastly, use Newtonsoft to deserialize the JSON from the service call into the class you created:
var json = Service.GetJson();
var yourDesiralizedJson = JsonConvert.DeserializeObject<YourJsonToCSharpClass>(json);
var listYouWant = yourDesiralizedJson.IWantChildList.IWantThis;
The below link is appears to be close to the solution as the requester using NewtonSoft.Json as his api to manipulate the object. Appreciate the solutions from other users as well.
look at e.g. here newtonsoft.com/json/help/html/SerializingJSONFragments.htm
The best solution (imo) is to define classes that describe your JSON schema then use DeserializeObject, as suggested by ertdiddy. As a shortcut, you can use DeserializeAnonymousType with incomplete definitions of your schema, taking advantage of JSON's leniency. In your case, this code is working for me:
var testDataFromQuestion = #"
{
""blabla"":1,
""bbb"":false,
""blabla2"":{
""aaa"":25,
""bbb"":25,
""ccc"":0
},
""I_want_child_list_from_this"":{
""total"":15226,
""max_score"":1.0,
""I_want_this"":[
{
""A"":""val1"",
""B"":""val2"",
""C"":""val3""
},
{
""A"":""val1"",
""B"":""val2"",
""C"":""val3""
}
],
""more_blabla"": ""fff""
}";
var anonymousDefinitionOfJson = new {
I_want_child_list_from_this = new {
I_want_this = new Dictionary<string, string>[] {}
}
};
var fullDeserializationOfTestData =
JsonConvert.DeserializeAnonymousType(testDataFromQuestion,
anonymousDefinitionOfJson);
var stuffYouWant = insterestingBits.I_want_child_list_from_this.I_want_this;
Console.WriteLine($"The first thing I want is {stuffYouWant[0]["A"]}");
This outputs the expected value "val1". I'm anonymously defining the minimal classes that get just the data you want, then I'm asking Newtonsoft to parse just enough to populate those classes.
Related
I am writing a Web API with requirement where need to pass result class property values as array of Json in response of GET request.
Property class which will be passed as a actual result with Ok Status with object. ( I am mocking actual requirement)
public class ABC
{
public string Name {get;set;}
public string Address{get;set;}
}
I am following default JSONfor matter option which are available in dotnet core web api and it is converting all class attribute into single json element.
{
"Person" :
[
{
"Name": "ABCD",
"Address": "INDIA"
}
]
}
My requirement is to have data in Json format with array as below -
{
"Person" :
[
{"Name": "ABCD"},
{"Address": "INDIA"}
]
}
using Newtonsoft.Json;
use this method to convert obj to string:
JsonConvert.SerializeObject(object)
use this method to convert string to obj:
JsonConvert.DeserializeObject(string)
=== Updated my answer to reflect clarified details ===
Solution with Json.Net:
To get the JSON result that you're looking for, you'll need to create a custom serializer or build your JSON object with dynamic JTokens.
Here's an example using a dynamic JObject:
https://dotnetfiddle.net/EyL5Um
Code:
// Create sample object to serialize
var person = new ABC() { Name = "ABC", Address = "India" };
// Build JSON with dynamic JTokens
dynamic jsonObj = new JObject();
var token = new JArray();
token.Add(new JObject(
new JProperty("Name", person.Name)));
token.Add(new JObject(
new JProperty("Address", person.Address)));
jsonObj.Person = token;
// Print result to console
Console.WriteLine(jsonObj.ToString());
Note
In this form, the code above is not a scalable solution. But it should provide you with a starting point to then build up an iterative approach for the data you're working with.
References
Newtonsoft Documentation - Create JSON w/ Dynamic
I want to retrieve a collection of football leagues from an external api. The response from the server comes as shown below:
{
"api": {
"results": 1496,
"leagues": [
{
"league_id": 1,
.....
The returned object constists of an "api" field which hold "results" and "leagues". I would like deserialize the code and map it to League class objects in my code.
var jsonString = await ExecuteUrlAsync(filePath, url);
var results = JsonConvert.DeserializeObject<IEnumerable<LeagueEntity>>(jsonString);
jsonString is correct, but when the program hits second line I get an exception:
Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.IEnumerable".
I need to get to the "leagues" field in JSON file, and ignore the rest of the response. How to achieve that?
Assuming your LeagueEntity corresponds to the api.leagues[*] objects, you can use JsonConvert.DeserializeAnonymousType() to pick out and deserialize the interesting portions of the JSON:
var leagues = JsonConvert.DeserializeAnonymousType(jsonString,
new { api = new { leagues = default(List<LeagueEntity>) } })
?.api?.leagues;
This avoids the need to create an explicit data model for the api.leagues container objects. It should also be more efficient than pre-loading into a JToken hierarchy, then as a second step selecting and deserializing the api.leagues array.
Demo fiddle here.
(Alternatively, you could auto-generate a complete data model for the entire JSON using one of the answers from How to auto-generate a C# class file from a JSON string.)
I am using .NET 4.7, C#, JSON.NET, MVC 5
I have some input JSON:
[
{
"id" : 1
},
{
"id" : 2
},
{
"id" : 3
}
]
This is provided by a 3rd party API
Normally I would use code such as, to deserialize:
var content = await response.Content.ReadAsStringAsync();
JObject json = JObject.Parse(content);
orderList = JsonConvert.DeserializeObject<OrderList>(json.ToString());
However I am finding that:
JObject json = JObject.Parse(content);
Crashes out with the JSON in question. I strongly suspect that the surrounding "[" and "]" is the cause.
I would normally add :
{
items: [
to correct the input JSON.
Is there a better way, to deserialize it, as it seems this input JSON is incomplete although when I test it, it does seem to be valid JSON.
Possibly I should be using JArray instead of JObject?
Thanks in advance.
You are missing commas "," in the JSON. It should be like this:
[
{
"id" : 1
},
{
"id" : 2
},
{
"id" : 3
}
]
And you can deserialize it like that:
var content = await response.Content.ReadAsStringAsync();
var list = JsonConvert.DeserializeObject<List<MyClass>>(content);
Where list is a List<MyClass>
public class MyClass
{
public int id { get; set; }
}
You have 3 options:
Instead of JObject.Parse, use JArray.Parse because the JSON is an array, not an object. This is not the best way to achieve what you want.
Deserialise to a List<T> where T is a concrete class that contains the matching properties of the object. for example:
var result = JsonConvert.DeserializeObject<List<Order>>(json);
This is better, but...
The best option is not to read the HttpClient response as a string in the first place and let the framework do the work for you. You should use the ReadAsAsync<T> extension method. Internally, this uses a stream and is more efficient than first going to string. So for example:
List<Order> orders = await response.Content.ReadAsAsync<List<Order>>();
I work with an api, that returns a json formatted resultset of a database query.
I have an equivalent object or "model" for the results.
What is the best way to convert the json string into a list of this object?
Of course there are many threads about this, but no one fits my needs properly.
One of the solutions I've found was this:
var jobj = (JObject)JsonConvert.DeserializeObject(json);
var items = jobj.Children()
.Cast<JProperty>()
.Select(j => new
{
ID = j.Name,
Topic = (string)j.Value["Topic_ID"],
Moved = (string)j.Value["Moved_ID"],
Subject = (string)j.Value["subject"],
})
.ToList();
This seems pretty close to what I need. I need to be able to map the keys/values to the appropriate object attributes, which DOES already exist. So maybe you only need to change a few things to make it work for my object?
PS: I'm using Newtonsoft. Any solution for .NET or Newtonsoft or if needed any other library would be great!
I have recently been consuming data from a WebApi and i have been using the following code to convert the json object to an object to work with:
using (var client = new HttpClient())
{
var response = client.GetAsync(apiUri).Result;
// For single objects.
MyObject data = response.Content.ReadAsAsync<MyObject>().Result;
// For an array of objects
IEnumerable<MyObject> data = response.Content.ReadAsAsync<IEnumerable<MyObject>>().Result;
}
Hope this helps.
OK, so you have something like this:
public class MyObject
{
public int ID {get; set;}
public string Topic {get; set;}
public string Subject {get; set;}
}
And you want to instantiate an array of MyObjects with the properties coming from your JSON?
In that case you're just a bout there - you're currently creating a dynamic object with the same properties as MyObject, right? So all you need to do is create an actual MyObject instead:
.Select(j => new **MyObject()**
{
ID = j.Name,
Topic = (string)j.Value["Topic_ID"],
Moved = (string)j.Value["Moved_ID"],
Subject = (string)j.Value["subject"]
})
Note that if your json property names exactly match your C# ones (including case), you can do this as a one-liner with NewtonSoft: http://www.newtonsoft.com/json/help/html/SerializingJSON.htm. But to use that method you'd have to have an intermediate C# class to match your JSON, and then automap (or manually convert) those to MyObjects. Or you'd have to make sure your json and c# properties match exactly. But you're already very close to a quicker (though some would argue less elegant) solution.
Why aren't you deserializing the json into the object type directly? you can do it like this...
var obj = (YourType)JsonConvert.DeserializeObject(
json,
typeof(YourType),
new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Auto,
MissingMemberHandling=MissingMemberHandling.Ignore
});
or am I missing something in the question?
I don't think the title of this post explains what the problem is, but I didn't know how to word it.
Basically I have this response from an API of which I have no control over:
"variations":{
"1033308042319364133":{
"id":"1033308042319364133",
"order":null,
"created_at":"2015-07-20 13:45:45",
"updated_at":"2015-07-20 13:47:11",
"title":"Male",
"mod_price":"+0.00",
"modifier":1033306667720114205,
"product":0,
"difference":"+£0.00"
},
"1033308953984892967":{
"id":"1033308953984892967",
"order":null,
"created_at":"2015-07-20 13:47:34",
"updated_at":"2015-07-20 13:47:34",
"title":"Female",
"mod_price":"+0.00",
"modifier":1033306667720114205,
"product":0,
"difference":"+£0.00"
},
"1033309404260204585":{
"id":"1033309404260204585",
"order":null,
"created_at":"2015-07-20 13:48:27",
"updated_at":"2015-07-20 13:48:27",
"title":"Male (Junior)",
"mod_price":"+0.00",
"modifier":1033306667720114205,
"product":0,
"difference":"+£0.00"
},
"1033309540147265579":{
"id":"1033309540147265579",
"order":null,
"created_at":"2015-07-20 13:48:44",
"updated_at":"2015-07-20 13:48:44",
"title":"Female (Junior)",
"mod_price":"+0.00",
"modifier":1033306667720114205,
"product":0,
"difference":"+£0.00"
}
}
in my c# code I loop through variations like this:
// Get our child variants
var variations = model["variations"];
var IsNull = IsJTokenNull(variations);
var variants = !IsNull ? new List<VariationResponseModel>() : null;
// If we have some variations
if (!IsNull)
{
// Loop through our variations
foreach (var variant in variations)
{
// Add our variant to our list
variants.Add(CreateVariants(variant.First));
}
}
As you can see, I am using variant.First to select the object within the property. My question is, is this the best way to do this? It seems like an awful hack.
This looks like a .net Dictionary more than a list. If VariationResponseModel has the correct properties, you could just do:
var variants = JsonConvert.DeserializeObject<Dictionary<string, Variant>>(variations);
or using the JObject class
var variants = JObject.Parse(variations).ToObject<Dictionary<string, Variant>>();
Both approaches are equivalent, and assume that you got your input as a JSON string. If your input is already a JObject, you can just use:
var variants = variations.ToObject<Dictionary<string, Variant>>()
If you need the variants in a list/enumerable afterwards, just use variants.Values
(JsonConvert / JObject is from the Json.net deserializer)