Deserializing JSON data from Thomson Reuters API - c#

I need get data from this JSON file, but I'm not able to get the data using C# and Newtonsoft. Can anyone help me to solve this issue? The data is from the Thomson Reuters API. I've tried other articles, but it's always a failure.
JSON:
{
"RequestKey": {
"NameType": "RIC",
"Service": "IDN",
"Name": "AEDMYR=R"
},
"QoS": {
"TimelinessInfo": {
"TimeInfo": 0,
"Timeliness": "REALTIME"
},
"RateInfo": {
"TimeInfo": 0,
"Rate": "TICK_BY_TICK"
}
},
"Status": {
"StatusMsg": "OK",
"StatusCode": 0
},
"Fields": {
"Field": [
{
"Name": "HIGH_1",
"DataType": "Double",
"Double": 117.3428
},
{
"Name": "LOW_1",
"DataType": "Double",
"Double": 117.0143
},
{
"Name": "YRHIGH",
"DataType": "Double",
"Double": 121.8861
},
{
"Name": "YRLOW",
"DataType": "Double",
"Double": 95.205
},
{
"Name": "HIGH_TIME",
"DataType": "Utf8String",
"Utf8String": "03:33"
},
{
"Name": "LOW_TIME",
"DataType": "Utf8String",
"Utf8String": "02:55"
},
{
"Name": "BKGD_REF",
"DataType": "Utf8String",
"Utf8String": "UAEDir/MalayRgt"
},
{
"Name": "GEN_TEXT16",
"DataType": "Utf8String",
"Utf8String": "AED vs MYR"
},
{
"Name": "GV2_TEXT",
"DataType": "Utf8String",
"Utf8String": "AEDMYR"
},
{
"Name": "VALUE_TS1",
"DataType": "Utf8String",
"Utf8String": "08:48:00"
},
{
"Name": "VALUE_TS2",
"DataType": "Utf8String",
"Utf8String": "08:47:01"
},
{
"Name": "VALUE_TS3",
"DataType": "Utf8String",
"Utf8String": "08:46:01"
},
{
"Name": "MONTH_HIGH",
"DataType": "Double",
"Double": 118.0954
},
{
"Name": "MONTH_LOW",
"DataType": "Double",
"Double": 114.0702
},
{
"Name": "WEEK_HIGH",
"DataType": "Double",
"Double": 117.3428
},
{
"Name": "WEEK_LOW",
"DataType": "Double",
"Double": 116.8654
},
{
"Name": "SCALING",
"DataType": "Utf8String",
"Utf8String": "100"
},
{
"Name": "CF_ASK",
"DataType": "Double",
"Double": 117.4272
},
{
"Name": "CF_BID",
"DataType": "Double",
"Double": 117.2443
},
{
"Name": "CF_CLOSE",
"DataType": "Double",
"Double": 116.7792
},
{
"Name": "CF_DATE",
"DataType": "Utf8String",
"Utf8String": "23 DEC 2015"
},
{
"Name": "CF_HIGH",
"DataType": "Double",
"Double": 117.3428
},
{
"Name": "CF_LAST",
"DataType": "Double",
"Double": 117.2443
},
{
"Name": "CF_LOW",
"DataType": "Double",
"Double": 117.0143
},
{
"Name": "CF_NETCHNG",
"DataType": "Double",
"Double": 0.4651
},
{
"Name": "CF_OPEN",
"DataType": "Double",
"Double": 116.7792
},
{
"Name": "CF_SOURCE",
"DataType": "Utf8String",
"Utf8String": "ThomRtrs"
},
{
"Name": "CF_TICK",
"DataType": "Utf8String",
"Utf8String": "⇧"
},
{
"Name": "CF_TIME",
"DataType": "Utf8String",
"Utf8String": "08:48:00"
},
{
"Name": "CF_NAME",
"DataType": "Utf8String",
"Utf8String": "UAEDir/MalayRgt"
},
{
"Name": "BQOS",
"DataType": "Utf8String",
"Utf8String": "0"
},
{
"Name": "PQOS",
"DataType": "Utf8String",
"Utf8String": "RT"
},
{
"Name": "ConcreteService",
"DataType": "Utf8String",
"Utf8String": "IDN_FD3"
},
{
"Name": "MSG_TYPE",
"DataType": "Int32",
"Int32": 0
},
{
"Name": "REC_STATUS",
"DataType": "Int32",
"Int32": 0
}
]
}
}
Deserialization code:
var result = "";
using (var objStreamReader = new StreamReader("RetrieveItem_Response_2.json"))
{
result = objStreamReader.ReadToEnd();
}
JObject joResponse = JObject.Parse(result);
JArray joArray = (JArray)(joResponse["RetrieveItem_Response_2"]["ItemResponse"]);
List<Rootobject> objRootobject = JsonConvert.DeserializeObject<List<Rootobject>>(joArray.ToString());
C# Classes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class Rootobject
{
public Requestkey RequestKey { get; set; }
public Qos QoS { get; set; }
public Status Status { get; set; }
public Fields Fields { get; set; }
}
public class Requestkey
{
public string NameType { get; set; }
public string Service { get; set; }
public string Name { get; set; }
}
public class Qos
{
public Timelinessinfo TimelinessInfo { get; set; }
public Rateinfo RateInfo { get; set; }
}
public class Timelinessinfo
{
public int TimeInfo { get; set; }
public string Timeliness { get; set; }
}
public class Rateinfo
{
public int TimeInfo { get; set; }
public string Rate { get; set; }
}
public class Status
{
public string StatusMsg { get; set; }
public int StatusCode { get; set; }
}
public class Fields
{
public Field[] Field { get; set; }
}
public class Field
{
public string Name { get; set; }
public string DataType { get; set; }
public float Double { get; set; }
public string Utf8String { get; set; }
public int Int32 { get; set; }
}

It looks like you have all of your classes defined correctly. To deserialize the JSON you just need to do this:
Rootobject obj = JsonConvert.DeserializeObject<Rootobject>(result);
You can dump out the field values like this:
foreach (Field f in obj.Fields.Field)
{
string value;
switch (f.DataType)
{
case "Utf8String": value = f.Utf8String; break;
case "Double": value = f.Double.ToString(); break;
case "Int32": value = f.Int32.ToString(); break;
default: value = "(unknown)"; break;
}
Console.WriteLine(f.Name + ": " + value);
}
Fiddle: https://dotnetfiddle.net/JD3jPD

Related

Json.Net.Schema: How to generate a schema where only the [Required] properties are required?

I am writing a tool to work with resume.json files (project) and am creating a Json Schema to validate user input. I'm trying to automate this with Json.Net.Schema but the output always makes all properties required, regardless of whether the properties have the [Required] or [JsonRequired] attributes.
Schema Generation Code
var generator = new JSchemaGenerator
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
SchemaIdGenerationHandling = SchemaIdGenerationHandling.TypeName
};
var schema = generator.Generate(typeof(Resume));
var sb = new StringBuilder();
schema.WriteTo(new JsonTextWriter(
new IndentedTextWriter(
new StringWriter(sb),
" ")
)
{
Formatting = Formatting.Indented,
IndentChar = ' ', Indentation = 2,
QuoteName = true
}, new JSchemaWriterSettings
{
Version = SchemaVersion.Draft7
});
File.WriteAllText("E:\\resume.schema", sb.ToString());
Resume Class (and children)
public class Resume
{
[Required]
public Basics Basics { get; set; }
public Work[] Work { get; set; }
public Volunteer[] Volunteer { get; set; }
public Education[] Education { get; set; }
public Award[] Awards { get; set; }
public Publication[] Publications { get; set; }
public Skill[] Skills { get; set; }
public Language[] Languages { get; set; }
public Interest[] Interests { get; set; }
public Reference[] References { get; set; }
}
public class Award
{
[Required]
public string Title { get; set; }
public string Date { get; set; }
public string Awarder { get; set; }
public string Summary { get; set; }
}
public class Basics
{
[Required]
public string Name { get; set; }
public string Label { get; set; }
public Uri Picture { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Website { get; set; }
public string Summary { get; set; }
public Location Location { get; set; }
public Profile[] Profiles { get; set; }
}
public class Education
{
[Required]
public string Institution { get; set; }
public string Area { get; set; }
public string StudyType { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public string Gpa { get; set; }
public string[] Courses { get; set; }
}
public class Interest
{
[Required]
public string Name { get; set; }
public string[] Keywords { get; set; }
}
public class Language
{
[Required]
public string language { get; set; }
[Required]
public string Fluency { get; set; }
}
public class Location
{
public string Address { get; set; }
[Required]
public string PostalCode { get; set; }
[Required]
public string City { get; set; }
[Required]
public string CountryCode { get; set; }
public string Region { get; set; }
}
public class Profile
{
[Required]
public string Network { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Url { get; set; }
}
public class Publication
{
[Required]
public string Name { get; set; }
public string Publisher { get; set; }
public string ReleaseDate { get; set; }
public string Website { get; set; }
public string Summary { get; set; }
}
public class Reference
{
[Required]
public string Name { get; set; }
public string reference { get; set; }
}
public class Skill
{
[Required]
public string Name { get; set; }
[Required]
public string Level { get; set; }
public string[] Keywords { get; set; }
}
public class Volunteer
{
[Required]
public string Organization { get; set; }
[Required]
public string Position { get; set; }
public string Website { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
public string Summary { get; set; }
public string[] Highlights { get; set; }
}
public class Work
{
[Required]
public string Company { get; set; }
[Required]
public string Position { get; set; }
public string Website { get; set; }
[Required]
public string StartDate { get; set; }
public string EndDate { get; set; }
public string Summary { get; set; }
public string[] Highlights { get; set; }
}
Current Output
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "Resume",
"definitions": {
"Award": {
"$id": "Award",
"type": [
"object",
"null"
],
"properties": {
"title": {
"type": "string"
},
"date": {
"type": [
"string",
"null"
]
},
"awarder": {
"type": [
"string",
"null"
]
},
"summary": {
"type": [
"string",
"null"
]
}
},
"required": [
"title",
"date",
"awarder",
"summary"
]
},
"Basics": {
"$id": "Basics",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"label": {
"type": [
"string",
"null"
]
},
"picture": {
"type": [
"string",
"null"
],
"format": "uri"
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"summary": {
"type": [
"string",
"null"
]
},
"location": {
"$id": "Location",
"type": [
"object",
"null"
],
"properties": {
"address": {
"type": [
"string",
"null"
]
},
"postalCode": {
"type": "string"
},
"city": {
"type": "string"
},
"countryCode": {
"type": "string"
},
"region": {
"type": [
"string",
"null"
]
}
},
"required": [
"address",
"postalCode",
"city",
"countryCode",
"region"
]
},
"profiles": {
"$id": "Profile[]",
"type": [
"array",
"null"
],
"items": {
"$id": "Profile",
"type": [
"object",
"null"
],
"properties": {
"network": {
"type": "string"
},
"username": {
"type": "string"
},
"url": {
"type": "string"
}
},
"required": [
"network",
"username",
"url"
]
}
}
},
"required": [
"name",
"label",
"picture",
"email",
"phone",
"website",
"summary",
"location",
"profiles"
]
},
"Education": {
"$id": "Education",
"type": [
"object",
"null"
],
"properties": {
"institution": {
"type": "string"
},
"area": {
"type": [
"string",
"null"
]
},
"studyType": {
"type": [
"string",
"null"
]
},
"startDate": {
"type": [
"string",
"null"
]
},
"endDate": {
"type": [
"string",
"null"
]
},
"gpa": {
"type": [
"string",
"null"
]
},
"courses": {
"$id": "String[]",
"type": [
"array",
"null"
],
"items": {
"type": [
"string",
"null"
]
}
}
},
"required": [
"institution",
"area",
"studyType",
"startDate",
"endDate",
"gpa",
"courses"
]
},
"Interest": {
"$id": "Interest",
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": "string"
},
"keywords": {
"$id": "String[]",
"type": [
"array",
"null"
],
"items": {
"type": [
"string",
"null"
]
}
}
},
"required": [
"name",
"keywords"
]
},
"Language": {
"$id": "Language",
"type": [
"object",
"null"
],
"properties": {
"language": {
"type": "string"
},
"fluency": {
"type": "string"
}
},
"required": [
"language",
"fluency"
]
},
"Location": {
"$ref": "Location"
},
"Profile": {
"$ref": "Profile"
},
"Publication": {
"$id": "Publication",
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": "string"
},
"publisher": {
"type": [
"string",
"null"
]
},
"releaseDate": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"summary": {
"type": [
"string",
"null"
]
}
},
"required": [
"name",
"publisher",
"releaseDate",
"website",
"summary"
]
},
"Reference": {
"$id": "Reference",
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": "string"
},
"reference": {
"type": [
"string",
"null"
]
}
},
"required": [
"name",
"reference"
]
},
"Skill": {
"$id": "Skill",
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": "string"
},
"level": {
"type": "string"
},
"keywords": {
"$id": "String[]",
"type": [
"array",
"null"
],
"items": {
"type": [
"string",
"null"
]
}
}
},
"required": [
"name",
"level",
"keywords"
]
},
"Volunteer": {
"$id": "Volunteer",
"type": [
"object",
"null"
],
"properties": {
"organization": {
"type": "string"
},
"position": {
"type": "string"
},
"website": {
"type": [
"string",
"null"
]
},
"startDate": {
"type": [
"string",
"null"
]
},
"endDate": {
"type": [
"string",
"null"
]
},
"summary": {
"type": [
"string",
"null"
]
},
"highlights": {
"$id": "String[]",
"type": [
"array",
"null"
],
"items": {
"type": [
"string",
"null"
]
}
}
},
"required": [
"organization",
"position",
"website",
"startDate",
"endDate",
"summary",
"highlights"
]
},
"Work": {
"$id": "Work",
"type": [
"object",
"null"
],
"properties": {
"company": {
"type": "string"
},
"position": {
"type": "string"
},
"website": {
"type": [
"string",
"null"
]
},
"startDate": {
"type": "string"
},
"endDate": {
"type": [
"string",
"null"
]
},
"summary": {
"type": [
"string",
"null"
]
},
"highlights": {
"$id": "String[]",
"type": [
"array",
"null"
],
"items": {
"type": [
"string",
"null"
]
}
}
},
"required": [
"company",
"position",
"website",
"startDate",
"endDate",
"summary",
"highlights"
]
}
},
"type": "object",
"properties": {
"basics": {
"$ref": "Basics"
},
"work": {
"$id": "Work[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Work"
}
},
"volunteer": {
"$id": "Volunteer[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Volunteer"
}
},
"education": {
"$id": "Education[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Education"
}
},
"awards": {
"$id": "Award[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Award"
}
},
"publications": {
"$id": "Publication[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Publication"
}
},
"skills": {
"$id": "Skill[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Skill"
}
},
"languages": {
"$id": "Language[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Language"
}
},
"interests": {
"$id": "Interest[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Interest"
}
},
"references": {
"$id": "Reference[]",
"type": [
"array",
"null"
],
"items": {
"$ref": "Reference"
}
}
},
"required": [
"basics",
"work",
"volunteer",
"education",
"awards",
"publications",
"skills",
"languages",
"interests",
"references"
]
}
How do I get the schema generator to honor the Required attributes?
JSchemaGenerator has a property DefaultRequired:
Gets or sets the default required state of schemas.
For some reason, the default value for this property is Required.AllowNull, as shown in the source:
public JSchemaGenerator()
{
_schemaReferenceHandling = SchemaReferenceHandling.Objects;
_defaultRequired = Required.AllowNull;
}
If you change it to Required.Default, only those properties explicitly marked as required, e.g. with [Required] or [JsonProperty(Required = Required.Always)], will be listed as required in the schema:
var generator = new JSchemaGenerator
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
SchemaIdGenerationHandling = SchemaIdGenerationHandling.TypeName,
DefaultRequired = Required.Default,
};
The default value for DefaultRequired isn't documented, but probably should be. You might open an issue with Newtonsoft requesting a clarification to the documentation.
Demo fiddle here.

ElasticSearch: Why all my text fields in the index have keyword type?

I pushing new documents using NEST in pair with class with attributes.
Here is how I define a class:
public class PatientNestModel
{
[Text]
public string FirstName { get; set; }
[Text]
public string LastName { get; set; }
[Text]
public string MiddleName { get; set; }
[Date(Format = "dd-MM-yyyy")]
public DateTime BirthdayDate { get; set; }
[Keyword]
public string Gender { get; set; }
[Text]
public string Phone { get; set; }
[Nested]
public List<AdditionalContact> AdditionalContacts { get; set; }
[Boolean]
public bool Active { get; set; }
}
Here is how I pushing it:
var response = _esClient.Index(model, idx => idx.Index("patients_esindex"));
But then my index metadata looks with keyword type.
{
"state": "open",
"settings": {
"index": {
"creation_date": "1543806292300",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "3_J5ck_CTaCLEdhIbCC0ZQ",
"version": {
"created": "6030199"
},
"provided_name": "patients_esindex"
}
},
"mappings": {
"patientnestmodel": {
"properties": {
"firstName": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"lastName": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"gender": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"birthdayDate": {
"type": "date"
},
"phone": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"active": {
"type": "boolean"
},
"middleName": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
}
}
}
},
"aliases": [],
"primary_terms": {
"0": 1,
"1": 1,
"2": 1,
"3": 1,
"4": 1
},
"in_sync_allocations": {
"0": [
"DCbu6-HvQT2ziCzhFZKU6A"
],
"1": [
"9SGADbBfSWuH7AanJUGgRA"
],
"2": [
"dPmhURTzTVWFV4z6Fh8ctw"
],
"3": [
"RHX67o0QQsueD6G67IXAkg"
],
"4": [
"aoBxi-i8Q1aVSeq1tT69Lw"
]
}
}
But then I am able to find the needed document by text search only if I used the term with .keyword
What am I do wrong?
Starting from ES 5.0, the string field has split into two new types: text, which should be used for full-text search, and keyword, which should be used for keyword search.
https://www.elastic.co/blog/strings-are-dead-long-live-strings
With Attribute mapping, you must call AutoMap() when creating the index, for the mapping from the attributes to be applied to your type in the index.
If the index has already been created, you can also use .Map<T>() with .AutoMap() to create the mapping for a type in the index, but this can only be done before indexing any documents (by default, Elasticsearch will infer the mapping from the first document indexed). If a mapping already exists for the type, you will either need to delete the index and start again, or reindex those documents into a new index that contains the expected mapping.

Deserialize json data c#

I want to deserialize JSON response received by Telegram Bot API by getUpdate() method.
JSON data:
{
"ok": true,
"result": [
{
"update_id": 920493886,
"message": {
"message_id": 123,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472457375,
"text": "Aata aala"
}
},
{
"update_id": 920493887,
"message": {
"message_id": 124,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472457387,
"text": "Jeva tuzyakadun reply aala tevha"
}
},
{
"update_id": 920493888,
"message": {
"message_id": 125,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472457443,
"text": "Deposite"
}
},
{
"update_id": 920493889,
"message": {
"message_id": 127,
"from": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k"
},
"chat": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k",
"type": "private"
},
"date": 1472457645,
"text": "\/menu",
"entities": [
{
"type": "bot_command",
"offset": 0,
"length": 5
}
]
}
},
{
"update_id": 920493890,
"message": {
"message_id": 128,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472457670,
"text": "\/menu",
"entities": [
{
"type": "bot_command",
"offset": 0,
"length": 5
}
]
}
},
{
"update_id": 920493891,
"message": {
"message_id": 130,
"from": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k"
},
"chat": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k",
"type": "private"
},
"date": 1472457848,
"text": "Deposite"
}
},
{
"update_id": 920493892,
"message": {
"message_id": 132,
"from": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k"
},
"chat": {
"id": 201520743,
"first_name": "Chandrakant",
"last_name": "Kumathekar",
"username": "chandrakant_k",
"type": "private"
},
"date": 1472457883,
"text": "Deposite"
}
},
{
"update_id": 920493893,
"message": {
"message_id": 133,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472468407,
"text": "\/menu",
"entities": [
{
"type": "bot_command",
"offset": 0,
"length": 5
}
]
}
},
{
"update_id": 920493894,
"message": {
"message_id": 134,
"from": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777"
},
"chat": {
"id": 219633031,
"first_name": "Shreeeeeee",
"username": "Winner7777",
"type": "private"
},
"date": 1472473070,
"text": "\/menu",
"entities": [
{
"type": "bot_command",
"offset": 0,
"length": 5
}
]
}
}
]
}
I have generated classes from json2csharp
public class From
{
public int id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string username { get; set; }
}
public class Chat
{
public int id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string type { get; set; }
public string username { get; set; }
}
public class Entity
{
public string type { get; set; }
public int offset { get; set; }
public int length { get; set; }
}
public class Message
{
public int message_id { get; set; }
public From from { get; set; }
public Chat chat { get; set; }
public int date { get; set; }
public string text { get; set; }
public List<Entity> entities { get; set; }
}
public class Result
{
public int update_id { get; set; }
public Message message { get; set; }
}
public class RootObject
{
public bool ok { get; set; }
public List<Result> result { get; set; }
}
using newtonsoft to deserialization
var d = Newtonsoft.Json.JsonConvert.DeserializeObject(rcvd_data);
what to do next? how to put this all at work? I am confused please help.
To deserialization use this code:
RootObject ro = JsonConvert.DeserializeObject<RootObject>(rcvd_data);
And in ro you have all data.
EXAMPLE
bool ok = ro.ok;
foreach(Result r in ro.result)
{
int uId = r.update_id;
Message m = r.message;
int msgId = m.message_id;
}
string data = #"{""ok"":true,""result"":[{""update_id"":920493886,...";
RootObject ro = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(data);
foreach (Result result in ro.result)
{
//two example fields
Console.WriteLine("update_id= " + result.update_id);
Console.WriteLine("message text= "+result.message.text);
}
Based on: https://yts.am/api/v2/list_movies.json (Source: https://yts.am/api)
I used: http://json2csharp.com/ to create classes
Copy and paste the result of the get request of postman to json2csharp to automatically create the classes that you need
And once created, i used them on a Service like this:
private string URL = "https://yts.am/api/v2/list_movies.json";
public async Task<List<Movie>> GetMovies()
{
var httpClient = new HttpClient();
var json = await httpClient.GetStringAsync(URL);
RootObject lista = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(json);
List<Movie> todoes = lista.data.movies;
return todoes;
}
I'm using Newtonsoft.Json
Try this way
var d = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(rcvd_‌​data);
then d will contain list of RootObject. By iterating using foreach you can get all the properties of RootObject model

Difficulty deserialising nested JSON

I am calling a REST service to get back a JSON structure.
The error I get is
Test method BarPanda.Web.Services.Test.PosServiceTests.GetMenu threw exception:
System.MissingMethodException: No parameterless constructor defined for this object.
The original JSON is as follows (partial)
{
"count": 3,
"limit": 50,
"_links": {
"self": {
"etag": "b49a27c7e7c663af8d6a736e24fac7f5",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/categories/" ,
"profile": "https://panel.omnivore.io/docs/api#category_list" 
}
},
"_embedded": {
"categories": [
{
"id": "AdiRjiAp",
"name": "Drinks",
"_links": {
"items": {
"etag": "05dad4d734401321a4854cf4f0369102",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/categories/AdiRjiAp/items/" ,
"profile": "https://panel.omnivore.io/docs/api#menu-item_list" 
},
"self": {
"etag": "05dad4d734401321a4854cf4f0369102",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/categories/AdiRjiAp/" ,
"profile": "https://panel.omnivore.io/docs/api#category_retrieve" 
}
},
"_embedded": {
"items": [
{
"id": "gki84ia9",
"in_stock": true,
"modifier_groups_count": 0,
"name": "Soda",
"open": false,
"pos_id": "gki84ia9",
"price": 150,
"price_levels": [
{
"id": "Byineidy",
"price": 150
},
{
"id": "g4T4dTBj",
"price": 200
},
{
"id": "K6czkc8b",
"price": 250
}
],
"_links": {
"modifier_groups": {
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/items/gki84ia9/modifier_groups/" ,
"profile": "https://panel.omnivore.io/docs/api#modifier-group_list" 
},
"self": {
"etag": "c59b380aed5c1f33915b028b739df955",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/items/gki84ia9/" ,
"profile": "https://panel.omnivore.io/docs/api#menu-item_retrieve" 
}
}
},
{
"id": "doTaLTyg",
"in_stock": true,
"modifier_groups_count": 0,
"name": "Orange Juice",
"open": false,
"pos_id": "doTaLTyg",
"price": 175,
"price_levels": [
{
"id": "L4iqKid8",
"price": 175
},
{
"id": "K6T8MTzb",
"price": 300
}
],
"_links": {
"modifier_groups": {
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/items/doTaLTyg/modifier_groups/" ,
"profile": "https://panel.omnivore.io/docs/api#modifier-group_list" 
},
"self": {
"etag": "d3ae9754edb321f18e192ebea446baeb",
"href": "https://api.omnivore.io/0.1/locations/gcBdM7TL/menu/items/doTaLTyg/" ,
"profile": "https://panel.omnivore.io/docs/api#menu-item_retrieve" 
}
}
}
]
}
},
I am trying to deserialize it with the following code and object classes
var response = _client.Execute(request);
var converter = new JsonDeserializer();
var menu = converter.Deserialize<PosMenu>(response);
PosMenu
[DataContract]
public class PosMenu
{
[DataMember]
public int VenueId { get; set; }
[DataMember]
public int count { get; set; }
[DataMember]
public PosMenuEmbedded _embedded { get; set; }
}
PosMenuEmbedded
[DataContract]
public class PosMenuEmbedded
{
[DataMember]
public long UniqueId { get; set; }
[DataMember]
public PosMenuCategory[] categories { get; set; }
[DataMember]
public int PosMenuId { get; set; }
}
PosMenuCategory
[DataContract]
public class PosMenuCategory
{
}
Note: I have taken all properties out of this class for now just to see if I could get it working with a blank class, but alas not.
If I comment out the line in PosMenuEmbedded
public PosMenuCategory[] categories { get; set; }
It succeeds. If I put it back in, it fails, even with an empty class.
Can anyone suggest why this might be?
[DataMember]
public List<PosMenuCategory> categories { get; set; }

JSON Deserialization - handle property that can be a array

Question Background:
I am querying Amazons Product Advertising API and trying to desearlize the JSON response to a C# object.
The Issue:
I have received a deserialization error when the code attempts the conversion. I can't quite work out which part is causing the error though. The following shows the error I'm receiving:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type'System.Collections.Generic.List`1[ShoppingComparisonEngine.AWS.AwsCommon.Item]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'Items.Item.ASIN', line 1, position 612.
The code:
The following C# are what the Newtonsoft is attempting to serialize to.
Item.cs:
public class Item
{
[JsonProperty("asin")]
public string ASIN { get; set; }
[JsonProperty("parentasin")]
public string ParentASIN { get; set; }
[JsonProperty("detailpageurl")]
public string DetailPageURL { get; set; }
[JsonProperty("salesrank")]
public string SalesRank { get; set; }
[JsonProperty("smallimage")]
public SmallImage SmallImage { get; set; }
[JsonProperty("mediumimage")]
public MediumImage MediumImage { get; set; }
[JsonProperty("largeimage")]
public LargeImage LargeImage { get; set; }
[JsonProperty("imagesets")]
public ImageSets ImageSets { get; set; }
[JsonProperty("itemattributes")]
public ItemAttributes ItemAttributes { get; set; }
[JsonProperty("offersummary")]
public OfferSummary OfferSummary { get; set; }
[JsonProperty("offers")]
public Offers Offers { get; set; }
}
Items.cs:
public class Items
{
[JsonProperty("totalresults")]
public string TotalResults { get; set; }
[JsonProperty("totalpages")]
public string TotalPages { get; set; }
[JsonProperty("moresearchresultsurl")]
public string MoreSearchResultsUrl { get; set; }
[JsonProperty("item")]
public List<Item> Item { get; set; }
}
JSON:
I believe this is an issue with the fact I have a singe Item whereas the conversion requires a list of them?
{
"Items": {
"xmlns": "http://webservices.amazon.com/AWSECommerceService/2011-08-01",
"Request": {
"IsValid": "True",
"ItemSearchRequest": {
"Availability": "Available",
"Condition": "New",
"ItemPage": "6",
"Keywords": "champagne bucket",
"ResponseGroup": [
"Medium",
"Offers"
],
"SearchIndex": "HomeGarden"
}
},
"TotalResults": "51",
"TotalPages": "6",
"MoreSearchResultsUrl": "http://www.amazon.co.uk/gp/redirect.html?linkCode=xm2&SubscriptionId=AKIAIFERUZJXWJ3Y2USA&location=http%3A%2F%2Fwww.amazon.co.uk%2Fgp%2Fsearch%3Fkeywords%3Dchampagne%2Bbucket%26url%3Dsearch-alias%253Doutdoor&tag=compar0c2-21&creative=12734&camp=2025",
"Item": {
"ASIN": "B00IYO4HRQ",
"DetailPageURL": "http://www.amazon.co.uk/Bottle-Holder-Accessories-Garden-Maintenance/dp/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00IYO4HRQ",
"ItemLinks": {
"ItemLink": [
{
"Description": "Add To Wishlist",
"URL": "http://www.amazon.co.uk/gp/registry/wishlist/add-item.html%3Fasin.0%3DB00IYO4HRQ%26SubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ"
},
{
"Description": "Tell A Friend",
"URL": "http://www.amazon.co.uk/gp/pdp/taf/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ"
},
{
"Description": "All Customer Reviews",
"URL": "http://www.amazon.co.uk/review/product/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ"
},
{
"Description": "All Offers",
"URL": "http://www.amazon.co.uk/gp/offer-listing/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ"
}
]
},
"SmallImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"MediumImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL160_.jpg",
"Height": {
"Units": "pixels",
"value": "160"
},
"Width": {
"Units": "pixels",
"value": "160"
}
},
"LargeImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL.jpg",
"Height": {
"Units": "pixels",
"value": "300"
},
"Width": {
"Units": "pixels",
"value": "300"
}
},
"ImageSets": {
"ImageSet": [
{
"Category": "swatch",
"SwatchImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL30_.jpg",
"Height": {
"Units": "pixels",
"value": "30"
},
"Width": {
"Units": "pixels",
"value": "30"
}
},
"SmallImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"ThumbnailImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"TinyImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL110_.jpg",
"Height": {
"Units": "pixels",
"value": "110"
},
"Width": {
"Units": "pixels",
"value": "110"
}
},
"MediumImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL160_.jpg",
"Height": {
"Units": "pixels",
"value": "160"
},
"Width": {
"Units": "pixels",
"value": "160"
}
},
"LargeImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL.jpg",
"Height": {
"Units": "pixels",
"value": "300"
},
"Width": {
"Units": "pixels",
"value": "300"
}
}
},
{
"Category": "primary",
"SwatchImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL30_.jpg",
"Height": {
"Units": "pixels",
"value": "30"
},
"Width": {
"Units": "pixels",
"value": "30"
}
},
"SmallImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"ThumbnailImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"TinyImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL110_.jpg",
"Height": {
"Units": "pixels",
"value": "110"
},
"Width": {
"Units": "pixels",
"value": "110"
}
},
"MediumImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL160_.jpg",
"Height": {
"Units": "pixels",
"value": "160"
},
"Width": {
"Units": "pixels",
"value": "160"
}
},
"LargeImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL.jpg",
"Height": {
"Units": "pixels",
"value": "300"
},
"Width": {
"Units": "pixels",
"value": "300"
}
}
}
]
},
"ItemAttributes": {
"Brand": "Garden at Home",
"EAN": "5971458914919",
"EANList": {
"EANListElement": "5971458914919"
},
"Feature": "Wine Bottle Holder and Cooler Bag Wine Accessories",
"Label": "Outdoor&Lawn",
"Manufacturer": "Outdoor&Lawn",
"MPN": "GG_89773368",
"PartNumber": "GG_89773368",
"ProductGroup": "Lawn & Patio",
"ProductTypeName": "OUTDOOR_LIVING",
"Publisher": "Outdoor&Lawn",
"Studio": "Outdoor&Lawn",
"Title": "Wine Bottle Holder and Cooler Bag Wine Accessories, Garden, Lawn, Maintenance"
},
"OfferSummary": {
"LowestNewPrice": {
"Amount": "5220",
"CurrencyCode": "GBP",
"FormattedPrice": "£52.20"
},
"TotalNew": "1",
"TotalUsed": "0",
"TotalCollectible": "0",
"TotalRefurbished": "0"
},
"Offers": {
"TotalOffers": "1",
"TotalOfferPages": "1",
"MoreOffersUrl": "http://www.amazon.co.uk/gp/offer-listing/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ",
"Offer": {
"OfferAttributes": {
"Condition": "New"
},
"OfferListing": {
"OfferListingId": "kif7varXuUaD7y55JfdjU7h3YCJvQokyXfgDIWvxOx6%2FqiMbxoPBsyFWCmgo8pbOqZNcezFUCBSdlx3JtRpEpe4Tu7VGv9zncLOYVmoSOUEDNQf1rrKJzZVCjnVPRCKyes0GSlEzlx%2Faht4%2FtjijlvCo14Z3CCcm",
"Price": {
"Amount": "5800",
"CurrencyCode": "GBP",
"FormattedPrice": "£58.00"
},
"SalePrice": {
"Amount": "5220",
"CurrencyCode": "GBP",
"FormattedPrice": "£52.20"
},
"AmountSaved": {
"Amount": "580",
"CurrencyCode": "GBP",
"FormattedPrice": "£5.80"
},
"PercentageSaved": "10",
"Availability": "Usually dispatched within 1-2 business days",
"AvailabilityAttributes": {
"AvailabilityType": "now",
"MinimumHours": "24",
"MaximumHours": "48"
},
"IsEligibleForSuperSaverShipping": "0",
"IsEligibleForPrime": "0"
}
}
},
"EditorialReviews": {
"EditorialReview": {
"Source": "Product Description",
"Content": "Ice Bucket Bag and Wine Cooler This unique Ice Bucket Bag is attractive and very durable. It is ideal for transporting wine to a friend, hostess or party and arriving with it perfectly chilled.Transparent and waterproof, this wine or Champagne bag also makes a super, space-saving ice bucket that simply folds away after use. It is especially ideal for a picnic or BBQ as it can fold for easy transport and is unbreakableIn addition, this bag makes a great party favor - comes with pocket for place card, business card or gift card. Heavy duty plastic measures 4\" x 4\" x 10\" when open, gift card slot measures 2\" x 3\".",
"IsLinkSuppressed": "0"
}
}
}
}
EDIT:
This is the code I used to create a Converter to handle both a singular Item object and a List of them.
public class ItemConverter:JsonConverter
{
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
List<Item> items = serializer.Deserialize<List<Item>>(reader);
return items;
}
else
{
Item itemList = serializer.Deserialize<Item>(reader);
return new List<Item>(new[] { itemList });
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
The Item property in the JSON is a plain object, not a list of objects. If it was supposed to be a list, then the JSON would be enclosed in square brackets to indicate it is an array, e.g.:
"Item": [{ item1 }, { item2}, ... ]
So you need to change your model to match. For example:
public class Items
{
//snip
public Item Item { get; set; }
}
.Net Fiddle: https://dotnetfiddle.net/9MACjN
You had multiple issues:
You are actually missing the closing } in your json.
You need to deserialize into a parent class (e.g., Response) that contains Items.
The Items.Item property needs to be of type Item, not List<Item>, as David said.
JsonProperty attributes are not needed at all.
Then it works.

Categories