I have the following JSON:
{
"id": "3cf5373c-9181-4639-89f0-bb64b387f961",
"display": "Data 1",
"country": "AU"
}
and I know how to construct the class to serialize it:
[DataContract]
public class myJSONClass
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "display")]
public string Display { get; set; }
[DataMember(Name = "country")]
public string Country { get; set; }
}
and I use the below to serialize:
var url = "http://myJSONAPI/";
var syncClient = new WebClient();
var content = syncClient.DownloadString(url);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(myJSONClass));
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
{
var jsonData = (myJSONClass)serializer.ReadObject(ms);
}
But how would I go about defining my class if my JSON is like the below?
[
{
"id": "3cf5373c-9181-4639-89f0-bb64b387f961",
"display": "My Data 1",
"country": "AU"
},
{
"id": "8886d2c8-0fd5-49ff-a3e1-7cef9e654514",
"display": "no test",
"country": null
}
]
How would like declare my class?
And how do I serialize it? I cannot use JSON.net as I cannot use newer .Net framework.
[] - It's array. So after deserialization you should get single array object of your class(myJSONClass)
myJSONClass[] deserializedData=deserialize(jsonData);
So if you want to get a deserialized array of objects you should just serialize not a single object but an array(several objects of your class)
But you doing something strange in example because you downloaded string and trying to serialize it. But you received serialized data(string is serialized. Object can be created by deserializing json(or xml) string).
So if you actually received 2 objects in array(as in your last JSON sample) your code should be more like this:
var url = "http://myJSONAPI/";
var syncClient = new WebClient();
var content = syncClient.DownloadString(url);
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(myJSONClass[]));
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
{
myJSONClass[] jsonObject = (myJSONClass[])serializer.ReadObject(ms);
}
I renamed some variables for better understanding. Also now you deserialize array of your class.
Also i found this thread: Deserialization of array with DataContractJsonSerializer with Windows Store App
But my own advice is to look at NewtonsoftJSON. It's really sweet
http://www.newtonsoft.com/json/help/html/deserializeobject.htm
So then you could achieve everything jus by one line:
myJSONClass[] res = JsonConvert.DeserializeObject<myJSONClass[]>(json_string);
You can do some:
// Use for JavaScriptSerializer
using System.Web.Script.Serialization;
JavaScriptSerializer serializer = new JavaScriptSerializer();
List<myJSONClass> myList = serializer.Deserialize<List<myJSONClass>>(content);
// Use for JsonConvert
using Newtonsoft.Json;
List<myJSONClass> myList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<myJSONClass>>(content);
Hope this help!
Related
Im writing an API automation test with RestSharp.Any kind of help will be greatly appreciated!
I'm getting data values from the response & I need to write few values to my json file (which I will use for another test putting them as a body).
I managed to get 1 value from JArray but I need 2 more values and I cant wrap my head around how to do that.
Im attaching my api test code & the data I get from the response + the data I managed to write into my json file.
The value that I managed to get: FsNumber (declared it as financialNumber). What I need to add to the json: subjectName + subjectCode (they will be declared as companyName/companyCode). How do I access "Query" list with SubjectName/SubjectCode?
TEST
var queryResult = client.Execute<object>(request);
var data = JsonConvert.SerializeObject(queryResult.Data);
var jsonParse = JToken.Parse(data);
var fsObject = jsonParse.Value<JToken>("FinanceReportList");
var fsArray = fsObject.Value<JArray>("List");
foreach (var fs in fsArray)
{
var cfn = fs.Value<string>("FsNumber");
var queryObject = new DataQuery
{
financialNumber = cfn,
};
var queryObjectString = JsonConvert.SerializeObject(queryObject);
File.WriteAllText(#"C:\Users\TestAPI\myJsonWithValues.json", queryObjectString);
}
Data I get from the response:
{
"RequestDate": "2021-07-16",
"Message": "Active",
"ProductNumber": 666,
"Language": "EN",
"RequestId": "reqID666",
"Query": {
"SubjectCode": "MY-SUBJECT",
"SubjectName": "MY-NAME"
},
"FinanceReportList": {
"List": [
{
"FsNumber": "MY-NUMBER",
"Year": 2021,
So far I managed to get FsNumber to my myJsonWithValues.json file as this:
{"financialNumber":"MY-NUMBER","companyName":null,"companyCode":null}
What Im trying to do is, my json should look like
{"financialNumber":"MY-NUMBER","companyName":MY-NAME,"companyCode":MY-CODE}
You have to access "Query" object
var fsQuery = jsonParse.Value<JToken>("Query")
and use Children() method to access properties of "Query"
var children = fsQuery.Children();
It is a good practice to implement a class that encapsulates your resonse and deserialize it with JsonConvert.Deserialize eg.
public class Account
{
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList<string> Roles { get; set; }
}
Account account = JsonConvert.DeserializeObject<Account>(json);
Instead of using JObjects
Right now I have the following code to query my CosmosDB:
var streamIterator = containerLogs.GetItemQueryStreamIterator("SELECT * FROM mycontainer");
while (streamIterator.HasMoreResults)
{
var results = await streamIterator.ReadNextAsync();
var stream = results.Content;
using var reader = new StreamReader(stream);
string data = await reader.ReadToEndAsync();
// typeof what..?
//var dbDocuments = JsonConvert.DeserializeObject<???>(data);
}
The variable data will contain the following JSON:
{
"_rid": "wDhMAJ9xYHE=",
"Documents": [{
"id": "c05c4eee-32d4-458a-8ae8-d22dd0f93839",
"CustomProperty1": "Value 1",
"CustomProperty2": "Value 2",
"_rid": "wDhMAJ9xYHECAAAAAAAAAA==",
"_self": "dbs\/wDhMAA==\/colls\/wDhMAJ9xYHE=\/docs\/wDhMAJ9xYHECAAAAAAAAAA==\/",
"_etag": "\"00000000-0000-0000-7167-28c107aa01d6\"",
"_attachments": "attachments\/",
"_ts": 1597319093
}],
"_count": 1
}
The Documents part is my actual "domain" model. How can I easily map this back to a list of my domain model class? I used the same class to write to CosmosDB.
The model looks like this
public class MyModel
{
[JsonProperty(PropertyName = "id")]
public Guid Id {get;set;}
public string CustomProperty1 {get;set;}
public string CustomProperty1 {get;set;}
}
So how can I query my CosmosDB so that it returns a list of this class?
Here are some samples that I found helpful. The simpler case is to used the typed GetItemQueryIterator<MyModel>, but there is also a stream deserialization example.
I have been trying to convert Json response to C# Array and the thing is Json goes up from my head I dont understand its structure as its a mess for me.
here is the example response I have as Json
{
"status":"ok",
"urls":{
"phone":[
{
"url":"tel:+9230154XXXXX",
"uri":"+9230154XXXXX"
}
],
"sms":{
"url":"sms:+9230154XXXXX",
"uri":"+9230154XXXXX"
},
"vcf":"https:\/\/www.eac.com\/i2\/ajax\/item\/vcf\/"
},
"limitExceeded":false
}
Now all i want from this Json sms:+9230154XXXXX this value.
I am using Newtonsoft.Json in this example.
Bellow is what I have tried so far
JObject jObject = JObject.Parse(json);
JToken jphone = jObject["urls"];
number = (string)jphone["phone"]["sms"];
Usage:
jObject["urls"]["phone"].ToObject<PhoneEntry[]>()
Class:
public class PhoneEntry {
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("uri")]
public string Uri { get; set; }
}
I never really worked with Newtonsoft.Json but the following should work for you:
JToken token = JToken.Parse(json);
string number = (string)token.SelectToken("urls.sms.url")
I am faced with a problem.
I want to deserialize a complex JSON response from a server, but I only need one part of it.
Here is an example:
{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}
}
I also used Csharp2json to get the class objects that I need, I just modified the menu class according to my needs :
public class Menuitem
{
public string value { get; set; }
public string onclick { get; set; }
}
public class Popup
{
public IList<Menuitem> menuitem { get; set; }
}
public class Menu
{
public Popup popup { get; set; }
}
public class RootObjectJourney
{
public Menu menu { get; set; }
}
Now, how do I deserialize if I only need the popup value and his children?
You can actually utilize the Linq namespace of the NewtonSoft.Json and modify your code little bit to get only the "popup" elements from the JSON.
your class structure remains the same. Make sure you use the namespace(s)
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
then in your code once you have the JSON string with you, you can use the "JObject" static method "Parse" to parse the JSON, like
var parsedObject = JObject.Parse(jsonString);
This will give you the JObject with which you can access all your JSON Keys just like a Dictionary.
var popupJson = parsedObject["menu"]["popup"].ToString();
This popupJson now has the JSON only for the popup key.
with this you can use the JsonConvert to de- serialize the JSON.
var popupObj = JsonConvert.DeserializeObject<Popup>(popupJson);
this popupObj has only list of menuitems.
If you do not use Newtonsoft and are using System.Text.Json in .NET Core, you can use this:
var post = JsonDocument.Parse(stringifiedJson);
var cat = post.RootElement.GetProperty("category").GetString();
You see GetString here to cast the value to string, there are other overloads available to cast the json value to Int32 etc.
If the intend is to deserialize only one property, I generally perefer to use JsonPath due to its flexibility. Please check the code below
var jsonQueryString = "{ 'firstName': 'John',
'lastName' : 'doe',
'age' : 26,}";
JObject o = JObject.Parse(jsonQueryString);
JToken token= o.SelectToken("$.age");
Console.WriteLine(token);
If your Json is complex, you can use power of JsonPath.
you can check https://support.smartbear.com/readyapi/docs/testing/jsonpath-reference.html#examples for JsonPath detailed documentation and examples.
I also included example below for further usage information:
JObject o = JObject.Parse(#"{
'store': {
'book': [
{
'category': 'history',
'author': 'Arnold Joseph Toynbee',
'title': 'A Study of History',
'price': 5.50
},
...
]
},
'expensive': 10
}");
//gets first book object
Console.WriteLine(o.SelectToken("$..book[0]"));
//get first book's title
Console.WriteLine(o.SelectToken("$..book[0].title"));
// get authors of the books where the books are cheaper then 10 $
foreach (var token in o.SelectTokens("$..[?(#.price < 10)].author"))
Console.WriteLine(token);
.NET 5+
The solution is very simple:
using System.Text.Json;
var doc = JsonDocument.Parse(response.Content);
var popupJson= doc.RootElement.GetProperty("menu").GetProperty("popup");
Does anyone know how to convert a string which contains json into a C# array. I have this which reads the text/json from a webBrowser and stores it into a string.
string docText = webBrowser1.Document.Body.InnerText;
Just need to somehow change that json string into an array. Been looking at Json.NET but I'm not sure if that's what I need, as I don't want to change an array into json; but the other way around. Thanks for the help!
just take the string and use the JavaScriptSerializer to deserialize it into a native object. For example, having this json:
string json = "[{Name:'John Simith',Age:35},{Name:'Pablo Perez',Age:34}]";
You'd need to create a C# class called, for example, Person defined as so:
public class Person
{
public int Age {get;set;}
public string Name {get;set;}
}
You can now deserialize the JSON string into an array of Person by doing:
JavaScriptSerializer js = new JavaScriptSerializer();
Person [] persons = js.Deserialize<Person[]>(json);
Here's a link to JavaScriptSerializer documentation.
Note: my code above was not tested but that's the idea Tested it. Unless you are doing something "exotic", you should be fine using the JavascriptSerializer.
using Newtonsoft.Json;
Install this class in package console
This class works fine in all .NET Versions, for example in my project: I have DNX 4.5.1 and DNX CORE 5.0 and everything works.
Firstly before JSON deserialization, you need to declare a class to read normally and store some data somewhere
This is my class:
public class ToDoItem
{
public string text { get; set; }
public string complete { get; set; }
public string delete { get; set; }
public string username { get; set; }
public string user_password { get; set; }
public string eventID { get; set; }
}
In HttpContent section where you requesting data by GET request
for example:
HttpContent content = response.Content;
string mycontent = await content.ReadAsStringAsync();
//deserialization in items
ToDoItem[] items = JsonConvert.DeserializeObject<ToDoItem[]>(mycontent);
Yes, Json.Net is what you need. You basically want to deserialize a Json string into an array of objects.
See their examples:
string myJsonString = #"{
"Name": "Apple",
"Expiry": "\/Date(1230375600000+1300)\/",
"Price": 3.99,
"Sizes": [
"Small",
"Medium",
"Large"
]
}";
// Deserializes the string into a Product object
Product myProduct = JsonConvert.DeserializeObject<Product>(myJsonString);
Old question but worth adding an answer if using .NET Core 3.0 or later. JSON serialization/deserialization is built into the framework (System.Text.Json), so you don't have to use third party libraries any more. Here's an example based off the top answer given by #Icarus
using System;
using System.Collections.Generic;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var json = "[{\"Name\":\"John Smith\", \"Age\":35}, {\"Name\":\"Pablo Perez\", \"Age\":34}]";
// use the built in Json deserializer to convert the string to a list of Person objects
var people = System.Text.Json.JsonSerializer.Deserialize<List<Person>>(json);
foreach (var person in people)
{
Console.WriteLine(person.Name + " is " + person.Age + " years old.");
}
}
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
}
}
One Situation that wasn't covered in the other responses is when you don't know the type of what the JSON object contains. That was my case as I needed to be able to NOT type it and leave it dynamic.
var objectWithFields = js.Deserialize<dynamic[]>(json);
Note: it is definitely preferred to have a type, in some cases, it is not possible, that's why I added this answer.