Here's the content of my object:
- tree {ItemTree} ItemTree
id "0" string
im0 null string
- item Count = 1 System.Collections.Generic.List<ItemTree>
- [0] {ItemTree} ItemTree
id "F_1" string
im0 "something.gif" string
+ item Count = 16 System.Collections.Generic.List<ItemTree>
parentId "0" string
text "someName" string
+ Raw View
parentId null string
text "" string
And I build it dynamically, so it's bigger.
It is an object from this class:
public class ItemTree
{
public String id { get; set; }
public String text { get; set; }
public List<ItemTree> item { get; set; }
public string im0 { get; set; }
public String parentId { get; set; }
}
So, the class ItemTree has a property which itself is a List of ItemTree objects.
I want to convert this to string. When I make:
tree.ToString()
I only get:
tree.ToString() "ItemTree" string
But I want to convert the whole tree structure to string. How to do this?
You need to override the ToString() method in your class.
When you create a custom class or struct, you should override the ToString method in order to provide information about your type to client code.
You can use XmlSerializer to serialize your object to XML.
You can Override the ToString Method of your class ItemTree
Or May be you can try with serializing with json-net
string json = JsonConvert.SerializeObject(tree);
You need to override the ToString method and print your tree representation there
public class ItemTree
{
public override string ToString()
{
return "Tree " + id +....
}
}
otherwise you will always see class name as result of base ToString()
If you override the ToString method, your implementation will be used by other code that calls ToString, simply because it's a standard method (inherited from Object).
Optionally you can implement a new method.
Either way, to avoid manually updating your method, you can generate a string using Json.Net like this:
string str = JsonConvert.SerializeObject(someObject);
Here is a sample from the documentation:
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "ExpiryDate": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
Nuget package: http://nuget.org/packages/Newtonsoft.Json/
Related
I want to parse below JSON in ASP.NET.
{
"destination_addresses": [
"Address 1"
],
"origin_addresses": [
"Address 2"
],
"rows": [
{
"elements": [
{
"distance": {
"text": "15.7 km",
"value": 15664
},
"duration": {
"text": "17 mins",
"value": 1036
},
"status": "OK"
}
]
}
],
"status": "OK"
}
I want to retrieve the text and value from a distance token. I was able to reach till elements.
var objectjson = JObject.Parse(response.Content);
dynamic dynJson = JsonConvert.DeserializeObject(objectjson["rows"].ToString());
var elements = dynJson[0].ToString();
var firstElement = JObject.Parse(elements);
How to parse the json further to reach to the distance token and then text and value?
Create a class like:
public class Distance {
public string text { get; set; }
public int value { get; set; }
}
public class Duration {
public string text { get; set; }
public int value { get; set; }
}
public class Element {
public Distance distance { get; set; }
public Duration duration { get; set; }
public string status { get; set; }
}
public class Row {
public List<Element> elements { get; set; }
}
public class Root {
public List<string> destination_addresses { get; set; }
public List<string> origin_addresses { get; set; }
public List<Row> rows { get; set; }
public string status { get; set; }
}
then, you can convert on it and construct your logic easylly
var myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
Sites references:
Json2Csharp
NewtonSoft
If you don't want to design a data model corresponding to your JSON, you can access nested JToken values using its item indexer:
var distance = objectjson["rows"]?[0]?["elements"]?[0]?["distance"];
var text = (string)distance?["text"];
var value = (decimal?)distance?["value"]; // Or int or double, if you prefer.
You can also use SelectToken() to access nested values:
var distance = objectjson.SelectToken("rows[0].elements[0].distance");
Notes:
There is no need to reformat and reparse the JSON simply to access nested data. I.e. JsonConvert.DeserializeObject(objectjson["rows"].ToString()) is superfluous and will harm performance.
I am using the null-conditional operator ?[] to access nested tokens in case any of the intermediate properties are missing. If you are sure the properties are never missing or would prefer to throw an exception, you can do
var distance = objectjson["rows"][0]["elements"][0]["distance"];
Demo fiddle here.
Take this sample json and:
Go to visual studio
In the menu -> Edit -> Paste Special -> Paste JSON and Classes
VS will generate the classes for you. It will generate the root type as Root, rename it to whatever you want or leave it as Root. Then you can simply deserialise your string into that class.
var rootObject = JsonConvert.DeserializeObject<Root>(response.Content);
// Simply use rootObject to access any property
var firstElement = rootObject.rows[0].elements[0];
// firstElement.distance.text
// firstElement.distance.value
// firstElement.duration.text
// firstElement.duration.value
// firstElement.status
You can traverse the data this way:
' strBuf = your json string
Dim jOb As JObject = JObject.Parse(strBuf)
Dim MyDistance As JToken = jOb.SelectToken("rows[0].elements[0]")
After above, then
Text = MyDistance.SelectToken("distance.text").ToString
value = MyDistance.SelectToken("distance.value").ToString
Status = MyDistance.SelectToken("status").ToString
The above will get you the 3 values. Note that each of the rows are repeating data, so it not clear if you have one string, and with to pull the values, or pull multiple values? If you need to pull repeating data, then above would change.
The above is vb, but it quite much the same in c#.
This question already has answers here:
How to write a JSON file in C#?
(4 answers)
Closed 2 years ago.
I have a JSON File as below ,
{
"student": {
"fullName": "No Name",
"id": 0001
},
"message": "Lets see if this is displayed!"
}
I want to write some logic in my WPF application where when someone clicks the submit button after filling in the corresoonding text fields those values will be serialized into this JSON.
In the sense for example if someone enters Dwayne as the name , 2222 as the ID and "Hello" as the message I want the JSON file to look as
{
"student": {
"fullName": "Dwayne",
"id": 2222
},
"message": "Hello"
}
Here is what I have implmented thus far in my code behind
I have the StudentData.cs class
public class StudentData
{
public StudentData()
{
}
public string Name { get; set; }
public string ID { get; set; }
public string Message { get; set; }
}
and in the xaml.cs where the save is executed I get the necessary data and save it as an object
string fullName = textName.Text;
string ID = textId.Text;
string message = textMessage.Text;
StudentData stuData = new StudentData();
stuData .Name = fullName;
stuData .ID = ID;
stuData .Message = message;
Can anyone help on what I can do next ?
You should use a JSON serialisation package, I prefer Newtonsoft.
https://www.newtonsoft.com/json
You would then serialise your data into JSON and write it like this:
List<StudentData> myStudentData = new List<StudentData>();
//Add data
string json = JsonConvert.SerializeObject(myStudentData);
File.WriteAllText("c:\\path\\to\\yourfile.json", json );
This will overwrite the file you specify with the new data.
BUT:
Your data structure is not correct to achieve the JSON you wish to output. So you either need to change your expectation of the output of the data, or would need to change your classes.
With the JSON example you have then message is only shown once for the whole output. If you want this then you need to use the following classes.
public class Student
{
public string fullName { get; set; }
public int id { get; set; }
}
public class RootObject
{
public List<Student> student { get; set; }
public string message { get; set; }
}
Then you will of course have to change your creation and output of objects like this;
RootObject root = new RootObject();
root.message = "Hello";
List<StudentData> myStudentData = new List<StudentData>();
//add data to student
root.student = myStudentData;
string json = JsonConvert.SerializeObject(root);
File.WriteAllText("c:\\path\\to\\yourfile.json", json );
If you wish for the message to be per student, then you keep your current class structure and you will get the following JSON output.
{
"student": {
"fullName": "Dwayne",
"id": 2222,
"message": "Hello"
}
}
You can use Newtonsoft.json library to convert your object to json.
var student = JsonConvert.SerializeObject(StudentData);
newtonsoft.json
I'm receiving from an API a result that is something like:
[{
"propID": 1,
"propname": "nameA",
"dataType": "N",
"value": "9"
},
{
"propID": 2,
"propname": "nameB",
"dataType": "VL",
"value": "dasdsa"
},
{
"propID": 3,
"propname": "nameC",
"dataType": "N",
"value": "7"
},
{
"propID": 4,
"propname": "nameD",
"dataType": "VL",
"value": "jmfidsnjfs"
}
]
I'm getting this and decoding this into an DTO so I can convert the numeric values into numerics.
My DTO looks like:
public class PropertyToInsertDto
{
[JsonIgnore]
public int propID { get; set; }
public string propname { get; set; }
[JsonIgnore]
public string dataType { get; set; }
[JsonIgnore]
public string value { get; set; }
public string valueString { get; set; }
public float valueInt { get; set; }
}
So, imagining I store the API into string variable called result I would decode this using
var properties = JsonConvert.DeserializeObject<List<PropertyToInsertDto>>(result);
and then iterating each property to convert into numeric values
foreach(var property in properties) {
if (string.IsNullOrEmpty(property.value))
continue;
if (property.dataType == "N") {
property.valueInt = float.Parse(property.value);
} else {
property.valueString = property.value;
}
}
I want to convert this into Json so the result is
{"nameA": 9, "nameB":"dasdsa", "nameC":7, "nameD": "jmfidsnjfs"}
I tried using the SerializeObject method from JsonConvert without any good result.
My biggest problem is due to the fact that the result can come from valueInt or valueString depending if it is a number or a text.
Thanks!
Kuno
First of all you ignored "value" property, so this property isn't deserialized by JsonConvert and always has default value.
[JsonIgnore]
public string value { get; set; }
"valueString" and "valueInt" aren't required in this DTO, you need separated DTOs to read and write because you are changing object structure.
You can get expected result using this code:
var properties = JsonConvert.DeserializeObject<List<PropertyToInsertDto>>(str);
var result = JsonConvert.SerializeObject(properties.ToDictionary(
x => x.propname,
x => x.dataType == "N" ? (object)float.Parse(x.value) : x.value));
You can create a dictionary and then convert it to a json like this:
https://www.newtonsoft.com/json/help/html/SerializeDictionary.htm
Instead of int type as the value you can use object. Or use a string even for number types, but you would have to use custom convert type when deserializing in the future operations.
This might help as well:
Serializing/Deserializing Dictionary of objects with JSON.NET
...and "beautiful" is sarcastic here.
When you call Active Campaign's list_view endpoint, and would like to get that in a json response, then this is the json response you get:
{
"0": {
"id": "4",
"name": "Nieuwsletter 1",
"cdate": "2018-11-22 03:44:19",
"private": "0",
"userid": "6",
"subscriber_count": 2901
},
"1": {
"id": "5",
"name": "Newsletter 2",
"cdate": "2018-11-22 05:02:41",
"private": "0",
"userid": "6",
"subscriber_count": 2229
},
"2": {
"id": "6",
"name": "Newsletter 3",
"cdate": "2018-11-22 05:02:48",
"private": "0",
"userid": "6",
"subscriber_count": 638
},
"result_code": 1,
"result_message": "Success: Something is returned",
"result_output": "json"
}
Now how would I ever be able to deserialize this to an object? Doing the normal Edit => Paste Special => Paste JSON As Classes gives me an output where I end up with classes that named _2.
Also, JsonConvert throws the following error: Accessed JObject values with invalid key value: 2. Object property name expected. So it is not really able to deserialize it either. I tried to use dynamic as object type to convert to.
The only thing I can think of now is replacing the first { by [ and the last } by ], then remove all the "1" : items and then remove the last 3 properties. After that I have a basic array which is easy convertable. But I kind of hope someone has a better solution instead of diving deep into the string.indexOf and string.Replace party...
If your key/value pair is not fixed and data must be configurable then Newtonsoft.json has one feature that to be used here and that is [JsonExtensionData]. Read more
Extension data is now written when an object is serialized. Reading and writing extension data makes it possible to automatically round-trip all JSON without adding every property to the .NET type you’re deserializing to. Only declare the properties you’re interested in and let extension data do the rest.
In your case key/value pair with 0,1,2,3.......N have dynamic data so your class will be
So create one property that collects all of your dynamic key/value pair with the attribute [JsonExtensionData]. And below I create that one with name DynamicData.
class MainObj
{
[JsonExtensionData]
public Dictionary<string, JToken> DynamicData { get; set; }
public int result_code { get; set; }
public string result_message { get; set; }
public string result_output { get; set; }
}
And then you can deserialize your JSON like
string json = "Your json here"
MainObj mainObj = JsonConvert.DeserializeObject<MainObj>(json);
Edit:
If you want to collect your dynamic key's value to class then you can use below the class structure.
class MainObj
{
[JsonExtensionData]
public Dictionary<string, JToken> DynamicData { get; set; }
[JsonIgnore]
public Dictionary<string, ChildObj> ParsedData
{
get
{
return DynamicData.ToDictionary(x => x.Key, y => y.Value.ToObject<ChildObj>());
}
}
public int result_code { get; set; }
public string result_message { get; set; }
public string result_output { get; set; }
}
public class ChildObj
{
public string id { get; set; }
public string name { get; set; }
public string cdate { get; set; }
public string _private { get; set; }
public string userid { get; set; }
public int subscriber_count { get; set; }
}
And then you can deserialize your JSON like
MainObj mainObj = JsonConvert.DeserializeObject<MainObj>(json);
And then you can access each of your deserialized data like
int result_code = mainObj.result_code;
string result_message = mainObj.result_message;
string result_output = mainObj.result_output;
foreach (var item in mainObj.ParsedData)
{
string key = item.Key;
ChildObj childObj = item.Value;
string id = childObj.id;
string name = childObj.name;
string cdate = childObj.cdate;
string _private = childObj._private;
string userid = childObj.userid;
int subscriber_count = childObj.subscriber_count;
}
I'd recommend JObject from the Newtonsoft.Json library
e.g. using C# interactive
// Assuming you've installed v10.0.1 of Newtonsoft.Json using a recent version of nuget
#r "c:\Users\MyAccount\.nuget\.nuget\packages\Newtonsoft.Json\10.0.1\lib\net45\Newtonsoft.Json.dll"
using Newtonsoft.Json.Linq;
var jobj = JObject.Parse(File.ReadAllText(#"c:\code\sample.json"));
foreach (var item in jobj)
{
if (int.TryParse(item.Key, out int value))
{
Console.WriteLine((string)item.Value["id"]);
// You could then convert the object to a strongly typed version
var listItem = item.Value.ToObject<YourObject>();
}
}
Which outputs:
4
5
6
See this page for more detail
https://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm
I am trying to retrieve data (just the phone number) from a nested JSON using Newtonsoft dll.
Json (request) looks something like this :
[{
"name": "sam",
"age": 19,
"Gender" : "F",
"Email" : "sam#test.com",
...
"PhoneNumber" :{
"CCode":"1",
"Area": "123",
"PhoneNum": "456-789",
"PhoneExtn": ""
}
...
}]
I have many more values in the json, but I need only phone number, so creating a Custom Class with above properties and using DeserializeObject on the above JSON string is not an option. However, I did try the below options:
dynamic jsonObj = JsonConvert.DeserializeObject(request);
var option1 = (string)jsonObj["PhoneNumber"]["CCode"];
var option2 = (string)jsonObj["PhoneNumber"][0]["CCode"];
//option3
PhoneNumberModel phone = JsonConvert.DeserializeObject<PhoneNumberModel>(jsonObj["PhoneNumber"].ToObject<string>());
//option4
PhoneNumberModel phone = JsonConvert.DeserializeObject<PhoneNumberModel>(jsonObj["PhoneNumber"][0].ToObject<string>());
Get these exceptions:
1. Cannot apply indexing with [] to an expression of type for first three options
2. Accessed JObject values with invalid key value: 0. Object property name expected for option 4.
I have tried many online solutions provided but none work. I am running out of options now.
Just define the properties that you need.
public class Person
{
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "PhoneNumber")]
public PhoneNumberModel { get; set; }
}
public class PhoneNumberModel
{
public int CCode { get; set;}
public int Area { get; set;}
public string PhoneNum { get; set; }
public string PhoneExtn { get; set; }
}
var person = JsonConvert.DeserializeObject<Person>(json);
var name = person.Name;
var phoneNumber = person.PhoneNumberModel;
Have you tried using the JsonConvert.DeserializeObject<T>(string) API but sending the whole request to it? Something like this:
PhoneNumberModel phone = JsonConvert.DeserializeObject<PhoneNumberModel>(request);
Newtonsoft ignores the missing properties in the target class.
You can get the PhoneNumber into your model like this:
PhoneNumberModel model =
JArray.Parse(json)[0]
.SelectToken("PhoneNumber")
.ToObject<PhoneNumberModel>();
Fiddle: https://dotnetfiddle.net/U21KfN