I am trying to parse a JSON response from a service to c# observation collection list object. The list object later can be used to showcase on the XAML page.
Here is the response from the service:
[
{
"orderId": 1,
"employeeId": "6364",
"orderTime": 1517583600000,
"orderCost": 90,
"comments": null,
"orderStatus": {
"orderStatusId": 1,
"orderStatusName": "Order Placed"
},
"orderedItems": [
{
"orderItemId": 1,
"orderQuantity": 1,
"orderItemCost": 50
},
{
"orderItemId": 2,
"orderQuantity": 1,
"orderItemCost": 40
}
]
},
{
"orderId": 2,
"employeeId": "6364",
"orderTime": 1517670000000,
"orderCost": 50,
"comments": null,
"orderStatus": {
"orderStatusId": 3,
"orderStatusName": "Order Delivered"
},
"orderedItems": [
{
"orderItemId": 3,
"orderQuantity": 1,
"orderItemCost": 50
}
]
}
]
The following is the model class :
namespace ServiceNew
{
public class OrderStatus
{
public int orderStatusId { get; set; }
public string orderStatusName { get; set; }
}
public class OrderedItem
{
[JsonProperty("orderItemId")]
public int orderItemId { get; set; }
[JsonProperty("orderQuantity")]
public int orderQuantity { get; set; }
[JsonProperty("orderItemCost")]
public int orderItemCost { get; set; }
}
public class Order
{
[JsonProperty("orderId")]
public int orderId { get; set; }
[JsonProperty("employeeId")]
public string employeeId { get; set; }
[JsonProperty("orderTime")]
public object orderTime { get; set; }
[JsonProperty("orderCost")]
public int orderCost { get; set; }
[JsonProperty("comments")]
public object comments { get; set; }
[JsonProperty("orderStatus")]
public OrderStatus orderStatus { get; set; }
[JsonProperty("orderedItems")]
public List<OrderedItem> orderedItems { get; set; }
}
}
The service is like this:
public class OrderService
{
public OrderService()
{
GetJson();
}
public async void GetJson()
{
if (NetworkCheck.IsInternet())
{
var client = new System.Net.Http.HttpClient();
var response = await client.GetAsync("here is thre URL");
string orderJson = await response.Content.ReadAsStringAsync(); //Getting response
Order ObjOrderList = new Order();
if (orderJson != " ")
{
Console.WriteLine("response is"+orderJson);
//exception occurs here all the time , and I need it to be a list
ObjOrderList = JsonConvert.DeserializeObject<Order>(orderJson);
}
Console.WriteLine("obj order list is"+ObjOrderList);
}
}
}
After trying with some changes to the deserialization the JSON array to c#, I was not able to succeed. Now there is an exception saying
Newtonsoft.Json.JsonSerializationException: <Timeout exceeded getting exception details>
And I am stuck at this for a long time, searched over StackOverflow and googled it but no fruitful solution for this.
I need to store the JSON data into a c# object and reproduce the same object in the XAML page as a list.
Thanks in advance!
I am sure that exception is not related to you JSON string but try to remove bin and obj from solution folder and then clean and rebuild solution.
but after resolving that you will get the below exception
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'namespace.Order' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.....
Because your JSON string is List of Order so the deserialize would be change to :
List<Order> ObjOrderList = JsonConvert.DeserializeObject<List<Order>>(orderJson);
or in the other side you can also use JavaScriptSerializer like:
Order[] orderList = new JavaScriptSerializer().Deserialize<Order[]>(orderJson);
You are deserializing a List of Orders so you should deserialize like this:
...
List<Order> ObjOrderList;
...
ObjOrderList = JsonConvert.DeserializeObject<List<Order>>(orderJson);
...
Your JSON starts with a [ and ends with a ]. This means that your JSON represents an array of objects. These objects are:
First object
{
"orderId": 1,
"employeeId": "6364",
"orderTime": 1517583600000,
"orderCost": 90,
...
}
Second object
{
"orderId": 2,
"employeeId": "6364",
"orderTime": 1517670000000,
"orderCost": 50,
...
}
In your subconscious you knew it, in fact the name of your deserialized variable is ObjOrderList (highlight List).
So, just deserialize to an array/list of Order.
Example with list
var ObjOrderList = new List<Order>();
if (orderJson != " ")
{
//exception occurs here all the time , and I need it to be a list
ObjOrderList = JsonConvert.DeserializeObject<List<Order>>(orderJson);
}
Example with array
var ObjOrderList = new Order[] { };
if (orderJson != " ")
{
//exception occurs here all the time , and I need it to be a list
ObjOrderList = JsonConvert.DeserializeObject<Order[]>(orderJson);
}
Try this autogenerated code:
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using yourNameSpace;
//
// var orderResponse = OrderResponse.FromJson(jsonString);
namespace yourNameSpace
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class OrderResponse
{
[JsonProperty("orderId")]
public long OrderId { get; set; }
[JsonProperty("employeeId")]
public string EmployeeId { get; set; }
[JsonProperty("orderTime")]
public long OrderTime { get; set; }
[JsonProperty("orderCost")]
public long OrderCost { get; set; }
[JsonProperty("comments")]
public object Comments { get; set; }
[JsonProperty("orderStatus")]
public OrderStatus OrderStatus { get; set; }
[JsonProperty("orderedItems")]
public List<OrderedItem> OrderedItems { get; set; }
}
public partial class OrderStatus
{
[JsonProperty("orderStatusId")]
public long OrderStatusId { get; set; }
[JsonProperty("orderStatusName")]
public string OrderStatusName { get; set; }
}
public partial class OrderedItem
{
[JsonProperty("orderItemId")]
public long OrderItemId { get; set; }
[JsonProperty("orderQuantity")]
public long OrderQuantity { get; set; }
[JsonProperty("orderItemCost")]
public long OrderItemCost { get; set; }
}
public partial class OrderResponse
{
public static List<OrderResponse> FromJson(string json) => JsonConvert.DeserializeObject<List<OrderResponse>>(json);
}
code was generated using QuickType.io
I discarded the converter and some other extra classes.
You can change the Long type to int if you want.
To use it just call
var orderResponse = OrderResponse.FromJson(jsonString);
pass the response instead of jsonString
In this Code you can DeserializeObject json file:
using (StreamReader r = new StreamReader("D:/Source/ParsijooWeatherApi/ParsijooWeatherApi/cities2.json"))
{
string json = r.ReadToEnd();
List<jsonVariables> items = JsonConvert.DeserializeObject<List<jsonVariables>>(json);
dynamic array = JsonConvert.DeserializeObject(json);
foreach (var item in array)
{
Console.WriteLine("{0} {1}", item.latitude, item.longitude);
}
}
jsonVariables class is:
public class jsonVariables
{
[JsonProperty("latitude")]
public string latitude { get; set; }
[JsonProperty("longitude")]
public string longitude { get; set; }
[JsonProperty("state")]
public string state { get; set; }
}
In this code you access to root directory project:
string _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
then:
StreamReader r = new StreamReader(_filePath + "/cities2.json"))
Related
sorry for my bad english. But i need a little help with this method (ToObject)
I have this class
namespace Proyects
{
public class AProductType
{
public DateTime CreationDate { get; set; }
public string Product { get; set; }
}
public class AProduct
{
public AProductType A_ProductType { get; set; }
}
public class AProductPlantType
{
public string SerialNumberProfile { get; set; }
}
public class ToPlant
{
public List<AProductPlantType> A_ProductPlantType { get; set; }
}
public class AProductDescriptionType
{
public string Language { get; set; }
public string Product { get; set; }
public string ProductDescription { get; set; }
}
public class ToDescription
{
public List<AProductDescriptionType> A_ProductDescriptionType { get; set; }
}
public class Root
{
public AProduct A_Product { get; set; }
public ToPlant to_Plant { get; set; }
public ToDescription to_Description { get; set; }
}
}
I am currently using the Root one to save a Jtoken in there. But i cant save the data on the propieties from Root class.
For example:
var object= myJson.ToObject<Root>();
If i try to save data on the propiety Product from AProductType, i cant access there using using ToOject. I try someting like this
var object= myJson.ToObject<Root>().A_Product.A_ProductType.Product;
And dont work, object var become null. I need some way to save the data around this complex object saving then in the propietes from Root.
Really sorry for my english, Thanks!!!
Edit: Json file
{
"A_Product": {
"A_ProductType": {
"CreationDate": "2020-01-17T00:00:00",
"Product": "158"
}
},
"to_Plant": {
"A_ProductPlantType": [
{
"SerialNumberProfile": "E001"
}
]
},
"to_Description": {
"A_ProductDescriptionType": [
{
"Language": "EN",
"Product": "158",
"ProductDescription": "Terminal LaP (nro de serie + equipo)"
},
{
"Language": "ES",
"Product": "158",
"ProductDescription": "Terminal LaP"
}
]
}
}
Edit 2:
private static List<string> retrieveData(JObject ob, List<Root> listaObjetos)
{
List<string> ListaCodigoProducto = new List<string>();
Root objetoRot = new Root();
var A_Product = ob["A_Product"];
if (A_Product.HasValues)
{
var validacion = ob["A_Product"]["A_ProductType"];
if (validacion.Type == JTokenType.Object)
{
var objeto = validacion.ToObject<AProductType>();
ListaCodigoProducto.Add(objeto.Product);
objetoRot.A_Product.A_ProductType.Product = objeto.Product;
listaObjetos.Add(objetoRot);
}
When i try to save the product number on
objetoRot.A_Product.A_ProductType.Product
It shows NullReference exception, i cant access to the propiety in the Root object
The deserializing code is working just fine. Your problem is that you're accessing objects that aren't there.
When you say Root objetoRot = new Root();, you are creating a new, empty Root. Its A_Product value will be null. A few lines down, you are saying objetoRot.A_Product.A_ProductType.Product = objeto.Product;. But you can't get objetoRot.A_Product.A_ProductType because there is no objetoRot.A_Product to access properties on.
I am using Newtonsoft.Json.JsonConvert.SerializeObject to convert a JsonPatchDocument<T> to string but it's value property (which is in JObject format) doesn't seem to be converted to string.
Here is what it looks like:
Here is the JSON I am using to create patchDocument object
[
{
"path": "/expenseLines/",
"op": "ReplaceById",
"value": {
"ExpenseLineId": 1,
"Amount": 4.0,
"CurrencyAmount": 4.0,
"CurrencyCode": "GBP",
"ExpenseDate": "2021-11-01T00:00:00",
"ExpenseType": "TAXI"
}
}
]
This JSON is successfully deserialized to JsonPatchDocument object but when I try to serialize it back to JSON, I lose value property (as shown in the picture by red arrows).
Any help would be appreciated :)
I can't reproduce your problem, can you provide more information? I got stuck during your second serialization. But I used using System.Text.Json to complete your needs, you can look at:
Model:
public class Test
{
public string path { get; set; }
public string op { get; set; }
public TestValue testValue { get; set; } = new TestValue();
}
public class TestValue
{
public int ExpenseLineId { get; set; }
public double Amount { get; set; }
public double CurrencyAmount { get; set; }
public string CurrencyCode { get; set; }
public DateTime ExpenseDate { get; set; }
public string ExpenseType { get; set; }
}
TestController:
[ApiController]
public class HomeController : Controller
{
[Route("test")]
public Object Index()
{
var patchDocument = new Test();
patchDocument.path = "/expenseLines/";
patchDocument.op = "ReplaceById";
patchDocument.testValue.ExpenseLineId = 1;
patchDocument.testValue.Amount = 4.0;
patchDocument.testValue.CurrencyAmount = 4.0;
patchDocument.testValue.CurrencyCode = "GBP";
patchDocument.testValue.ExpenseDate = DateTime.Now;
patchDocument.testValue.ExpenseType = "TAXI";
var options = new JsonSerializerOptions { WriteIndented = true };
// var content = JsonConvert.SerializeObject(patchDocument);
// string content1 = JsonConvert.SerializeObject(patchDocument.Operations);
string jsonString = System.Text.Json.JsonSerializer.Serialize<Test>(patchDocument);
string jsonString1 = System.Text.Json.JsonSerializer.Serialize(patchDocument, options);
return jsonString;
}
Result:
Hope this helps you too.
for two days I have been trying to understand how to move this JSON to an object in C#. I read a lot of topics and tried several ways to solve my problem, but still haven't solved it.
My JSON looks like this (cropped).
{
"data": [{
"id": 5643793,
"title": "It's a Title",
"description": "It's a Description.",
"tags": "#tag1 #tag2 #tag3 #tag4",
"source_url": "https:\/\/p.dw.com\/p\/3geny",
"vote_count": 120,
"bury_count": 17,
"comments_count": 33,
"related_count": 0,
"date": "2020-08-10 09:43:32",
"author": {
"login": "lnwsk",
"color": 2,
"avatar": "https:\/\/www.api.page.com\/cdn\/c3397992\/lnwsk_MfQz8MEQb2,q150.jpg"
},
"preview": "https:\/\/www.api.page.com\/cdn\/c3397993\/link_1597045214DgzqxRGEmy2UlpPZwaWfhI,w104h74.jpg",
"plus18": false,
"status": "promoted",
"can_vote": true,
"is_hot": false
}],
"pagination": {
"next": "https:\/\/api.page.com\/links\/promoted\/appkey\/X*******4y\/page\/2\/"
}
}
As you can see, there is an "element within an element" here (eg author or pagination (eg pagination I would like to get rid of)) and that is what gives me the most problem.
Here is my class where I have all the code to read the API:
using Newtonsoft.JSON;
public class PageAPI
{
public class Product
{
public string[] title { get; set; }
public double[] description { get; set; }
public string[] tags { get; set; }
public string[] source_url { get; set; }
public string[] vote_count { get; set; }
public string[] bury_count { get; set; }
public string[] comments_count { get; set; }
public string[] related_count { get; set; }
public string[] date { get; set; }
}
public async Task<Product> GetDataAsync()
{
string url = "https://api.page.com/";
string apisign = "6*********c1fe49a23f19ad6b2";
string requestParams = "links/promoted/appkey/X*******y";
Product obj = null;
// HTTP GET.
using (var client = new HttpClient())
{
// Setting Base address.
client.BaseAddress = new Uri(url);
// Setting content type.
client.DefaultRequestHeaders.Add("apisign", apisign);
// Initialization.
HttpResponseMessage response = new HttpResponseMessage();
// HTTP GET
response = await client.GetAsync(requestParams).ConfigureAwait(false);
// Verification
if (response.IsSuccessStatusCode)
{
try
{
// Reading Response.
string result = response.Content.ReadAsStringAsync().Result;
obj = JsonConvert.DeserializeObject<Product>(result);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
}
}
else
{
obj = null;
}
}
return obj;
}
}
in the Form where I want to get data from the "PageAPI" class I have:
private async void Form1_LoadAsync(object sender, EventArgs e)
{
var task = api.GetMainAsync();
task.Wait();
var data = task.Result;
label1.Text = data.title[0];
}
And... this doesn't works - on label1.Text = data.title[0]; i get error PageAPI.Product.title.get returned null
Thanks for any help!
You are missing the Root class that has "data" and "pagination" properties. Create Root class and deserialize to it and then get the data you need. Also, your Product class will have only strings.. not string[].
public class RootObject
{
public List<Product> data { get; set; }
}
public class Product
{
public string title { get; set; }
public double description { get; set; }
public string tags { get; set; }
public string source_url { get; set; }
public string vote_count { get; set; }
public string bury_count { get; set; }
public string comments_count { get; set; }
public string related_count { get; set; }
public string date { get; set; }
}
// and deserialize it
var rootObj = JsonConvert.DeserializeObject<RootObject>(result);
obj = rootObj.data.FirstOrDefault();
data object is an array ... you can loop through it to work with All the items. In above example, i used FirstOrDefault() to get the first item from the object.
Also note that when you access this data, you would not access it via [0]. Simply use
label1.Text = data.title;
Side Note
If you want the pagination property as well, create another class to get the name from pagination object.
public class RootObject {
public List<Product> data {get;set;}
public Pagination pagination {get;set;}
}
public class Pagination {
public string next {get;set; }
}
and when you deserialize your json, you would access the pagination by using,
Console.WriteLine(rootObj.pagination.next); // prints the url
How to get All the Product Names displayed
This is how you would go about getting a list of All the titles in the data object.
foreach (var product in rootObj.data)
{
Console.WriteLine(product.title);
Console.WriteLine(product.description);
Console.WriteLine(product.vote_count); // etc.
}
// Or you can create a list of all the titles from the rootObj using LINQ
List<string> allTitles = rootObj.data.Select(x => x.title).ToList();
I am not sure what you intend to do with the data you get... so not sure how to explain that piece.. but above example should give you an idea on how to iterate through all the products in the data object.
I want to get manuscript summary from PubMed. The content of each summary is in a JSON with the following format. The "29498802" is a unique ID, and it is different for each manuscript.
{
"header":{
"type":"esummary",
"version":"0.3"
},
"result":{
"uids":[
"29498802"
],
"29498802":{
"uid":"29498802",
"pubdate":"2018 Mar 2",
"epubdate":"2018 Mar 2",
...
}
}
}
I use Newtonsoft.Json in C# to deserialize the JSON to an class:
var summary = JsonConvert.DeserializeObject<Summary>(stringResult);
My Summary class is as follows:
public class Summary
{
[JsonProperty("header")]
public Header header { get; set; }
[JsonProperty("result")]
public Result result { get; set; }
}
public class Result
{
[JsonProperty("uids")]
public List<string> uids { get; set; }
public Dictionary<string, PubMedId> content { get; set; }
}
public class PubMedId
{
[JsonProperty("uid")]
public string uid { get; set; }
...
}
I was able to extract "header (type and version)", "uids", but "content" is always null. Any suggestions?
var summary = JsonConvert.DeserializeObject<Summary>(text);
var resultjO = JObject.Parse(text).Value<JObject>("result");
var pubdAsJObject = resultjO.Value<JObject>(summary.result.uids[0]);
var pubMed = JsonConvert.DeserializeObject<PubMedId>(pubdAsJObject.ToString());
"responseCode": String
"responseMessage": String
"responseBody": { "conversations": [
{
"conversationId": String,
"state": String,
"conversationType": String,
"mediaType": Enum,
"startDate":Integer,
"duration": Integer,
"tags":[{ "tagName":String,
"tagType":String,
"tagCreateDate":Integer,
"tagOffset":Integer
}],
]}
This schema continues, but my question regarding the first section applies to the rest...
How can I deserialize a JSON response based on this schema into .NET objects? what would the .NET object look like?
Is there another way to read it ? (like a .NET Dataset type of way?)
Thanks. Roey.
If you want (or have to) to use JavaScriptSerializer the code could look like following:
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
namespace JsonSer {
public class MyTag {
public string tagName { get; set; }
public string tagType { get; set; }
public long tagCreateDate { get; set; }
public int tagOffset { get; set; }
}
public enum MyMedia {
Diskette,
UsbStick,
Disk,
Internet
}
public class MyConversation {
public string conversationId { get; set; }
public string state { get; set; }
public string conversationType { get; set; }
public MyMedia mediaType { get; set; }
public long startDate { get; set; }
public int duration { get; set; }
public List<MyTag> tags { get; set; }
}
public class MyConversations {
public List<MyConversation> conversations { get; set; }
}
public class MyData {
public string responseCode { get; set; }
public string responseMessage { get; set; }
public MyConversations responseBody { get; set; }
}
class Program {
static void Main (string[] args) {
MyData data = new MyData () {
responseCode = "200",
responseMessage = "OK",
responseBody = new MyConversations () {
conversations = new List<MyConversation> () {
new MyConversation() {
conversationId = "conversation1",
state = "state1",
conversationType = "per JSON",
mediaType = MyMedia.Internet,
startDate = DateTime.Now.Ticks,
duration = 12345,
tags = new List<MyTag>() {
new MyTag() {
tagName = "tagName1",
tagType = "tagType1",
tagCreateDate = DateTime.Now.Ticks,
tagOffset = 1
}
}
}
}
}
};
Console.WriteLine ("The original data has responseCode={0}", data.responseMessage);
JavaScriptSerializer serializer = new JavaScriptSerializer ();
string json = serializer.Serialize (data);
Console.WriteLine ("Data serialized with respect of JavaScriptSerializer:");
Console.WriteLine (json);
MyData d = (MyData)serializer.Deserialize<MyData> (json);
Console.WriteLine ("After deserialization responseCode={0}", d.responseMessage);
}
}
}
the corresponding JSON data will be look like
{
"responseCode": "200",
"responseMessage": "OK",
"responseBody": {
"conversations": [
{
"conversationId": "conversation1",
"state": "state1",
"conversationType": "per JSON",
"mediaType": 3,
"startDate": 634207605160873419,
"duration": 12345,
"tags": [
{
"tagName": "tagName1",
"tagType": "tagType1",
"tagCreateDate": 634207605160883420,
"tagOffset": 1
}
]
}
]
}
}
You can easy modify the code if you decide to use DataContractJsonSerializer.
First you can beautify all your JSON using http://jsbeautifier.org/ to make it more readable, and then the only way I know is to just go through every property step by step and create classes for them. You should add the [DataContract] attribute for classes and the [DataMember] attribute for properties.
Example
[DataContract]
public class Response{
[DataMember]
public string responseCode {get;set;}
[DataMember]
public string responseMessage {get;set;}
[DataMember]
public ResponseBody responseBody {get;set;}
}
Automatic generation of these classes
There are alternatives for XMLSerialization (using XSD) but as far as I know there are no similar solutions for json thus far.
To finally deserialize the json into .NET object you can use the following code:
Response myResponse = new Person();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(myResponse.GetType());
myResponse = serializer.ReadObject(ms) as Response;
ms.Close();
Where Response would be the type of object that represents the root of your json.
For more information visit the MSDN page of the DataContractJsonSerializer class.