How can I debug the assignment of an object to a class? - c#

I am trying to assign this object as follows:
RootObject aaa = new RootObject() {
"word": "example",
"results": [
{
"definition": "a representative form or pattern",
"partOfSpeech": "noun",
"synonyms": [
"model"
],
"typeOf": [
"representation",
"internal representation",
"mental representation"
],
"hasTypes": [
"prefiguration",
"archetype",
"epitome",
"guide",
"holotype",
"image",
"loadstar",
"lodestar",
"microcosm",
"original",
"paradigm",
"pilot",
"prototype",
"template",
"templet",
"type specimen"
],
"derivation": [
"exemplify"
],
"examples": [
"I profited from his example"
]
},
{
"definition": "something to be imitated",
"partOfSpeech": "noun",
"synonyms": [
"exemplar",
"good example",
"model"
],
"typeOf": [
"ideal"
],
"hasTypes": [
"pacemaker",
"pattern",
"beauty",
"prodigy",
"beaut",
"pacesetter"
],
"derivation": [
"exemplify",
"exemplary"
]
},
{
"definition": "an occurrence of something",
"partOfSpeech": "noun",
"synonyms": [
"case",
"instance"
],
"typeOf": [
"happening",
"natural event",
"occurrence",
"occurrent"
],
"hasTypes": [
"clip",
"mortification",
"piece",
"time",
"humiliation",
"bit"
],
"derivation": [
"exemplify"
],
"examples": [
"but there is always the famous example of the Smiths"
]
},
{
"definition": "an item of information that is typical of a class or group",
"partOfSpeech": "noun",
"synonyms": [
"illustration",
"instance",
"representative"
],
"typeOf": [
"information"
],
"hasTypes": [
"excuse",
"apology",
"specimen",
"case in point",
"sample",
"exception",
"quintessence",
"precedent"
],
"derivation": [
"exemplify",
"exemplary"
],
"examples": [
"this patient provides a typical example of the syndrome",
"there is an example on page 10"
]
},
{
"definition": "punishment intended as a warning to others",
"partOfSpeech": "noun",
"synonyms": [
"deterrent example",
"lesson",
"object lesson"
],
"typeOf": [
"monition",
"admonition",
"word of advice",
"warning"
],
"derivation": [
"exemplary"
],
"examples": [
"they decided to make an example of him"
]
},
{
"definition": "a task performed or problem solved in order to develop skill or understanding",
"partOfSpeech": "noun",
"synonyms": [
"exercise"
],
"typeOf": [
"lesson"
],
"examples": [
"you must work the examples at the end of each chapter in the textbook"
]
}
],
"syllables": {
"count": 3,
"list": [
"ex",
"am",
"ple"
]
},
"pronunciation": {
"all": "ɪɡ'zæmpəl"
}
}
Here are the classes I defined:
public class Result
{
public string definition { get; set; }
public string partOfSpeech { get; set; }
public List<string> synonyms { get; set; }
public List<string> typeOf { get; set; }
public List<string> hasTypes { get; set; }
public List<string> derivation { get; set; }
public List<string> examples { get; set; }
}
public class Syllables
{
public int count { get; set; }
public List<string> list { get; set; }
}
public class Pronunciation
{
public string all { get; set; }
}
public class RootObject
{
public string word { get; set; }
public List<Result> results { get; set; }
public Syllables syllables { get; set; }
public Pronunciation pronunciation { get; set; }
}
I'm getting syntax errors starting on the first line with "word".
Is there a way I can debug this or at least find out what is causing the problem?

Try
RootObject aaa = JsonConvert.DeserializeObject<RootObject>(
put_your_string_from_the_question);
Download Json.Net from nuget.org

You simply cannot assign JSON object to C# Object. You need to assign properties of your class and DeSerialize that to JSON format.
in your case you should do like this way:
var roorObj= new RootObject()
{
word ="your word",
//
//
}
Then to get the JOSN string, use this:
RootObject aaa = JsonConvert.DeserializeObject<RootObject>(roorObj);
Hope you will get some idea to play with C# object and JSON.

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.

Problem with parsing JavaScript objects to C#

I'm parsing js file containing object values to C# objects. For now - I've converted JS code to JSON and then tried to convert to C# object.
I'm having problem with coming up to idea of how to generate objects in C#. I've tried doing multiple various tries, mostly with Dictionaries (Dictionary<string,[object]). I Googled, visited SO in multiple questions, no success for now - all my ideas resulted in null object.
Important note - I can't change the source of JS, can change anything after that.
Latest objects idea:
public class SingleFarm
{
public List<string> Modules { get; set; }
public List<string> Servers { get; set; }
}
public class SingleEnv
{
public Dictionary<string, SingleFarm> Farms { get; set; }
}
public class FarmsModel
{
public Dictionary<string, SingleEnv> FarmsModel { get; set; }
}
Parsing code:
var farmsText = File.ReadAllText(filePath);
//using Jurassic
var engine = new ScriptEngine();
var result = engine.Evaluate(farmsText);
var json = JSONObject.Stringify(engine, result);
var parsed = JsonConvert.DeserializeObject<FarmsModel>(json);
JS file source:
var environments = {};
environments['ENV1'] = {
"WWW": {
"Modules": [
"module21"
],
"Servers": [
"a-1"
]
}
};
environments['ENV2'] = {
"FARM1": {
"Modules": [
"module41"
],
"Servers": [
"s1",
"s2"
]
},
"FARM2": {
"Modules": [
"module11"
],
"Servers": [
""
]
},
"FARM3": {
"Modules": [
"module1"
],
"Servers": [
""
]
}
};
environments['ENV3'] = {
"FARM1": {
"Modules": [
"module10"
],
"Servers": [
"server1"
]
},
"FARM2": {
"Modules": [
"module22"
],
"Servers": [
""
]
},
"FARM3": {
"Modules": [
"module33"
],
"Servers": [
"server3"
]
}
};
JSON looks as follows:
{
"ENV1": {
"WWW": {
"Modules": [
"module21"
],
"Servers": [
"a-1"
]
}
},
"ENV2": {
"FARM1": {
"Modules": [
"module41"
],
"Servers": [
"s1",
"s2"
]
},
"FARM2": {
"Modules": [
"module11"
],
"Servers": [
""
]
},
"FARM3": {
"Modules": [
"module1"
],
"Servers": [
""
]
}
},
"ENV3": {
"FARM1": {
"Modules": [
"module10"
],
"Servers": [
"server1"
]
},
"FARM2": {
"Modules": [
"module22"
],
"Servers": [
""
]
},
"FARM3": {
"Modules": [
"module33"
],
"Servers": [
"server3"
]
}
}
}
Do you have any ideas?
You shouldn't be trying to serialize dictionaries to objects since it will try to map the property names.
If you use
var parsed = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, SingleFarm>>>(json);
It should work. Fiddle

Validation of an invalid json data with Schema not failing with Deserialization

I am parsing the following JSON:
{"names":{"organizationNames":[{"name":"apple"}]}}
into the schema defined in C# Code as shown below.
public class QueryJson
{
#region Properties
[JsonProperty("organization")]
public HeOrganization Organization { get; set; }
[JsonProperty("names")]
public HeName Names { get; set; }
[JsonProperty("emails")]
public List<HeEmailAddress> Emails { get; set; }
#endregion
#region Linked Classes
public class HeOrganization
{
[JsonProperty("id")]
public Guid? ID { get; set; }
}
public class HeName
{
[JsonProperty("organizationNames")]
[Required(ErrorMessage = "Organization Name is Missing")]
public List<HeOrganizationName> OrganizationName { get; set; }
public class HeOrganizationName
{
[JsonProperty("name")]
[Required(ErrorMessage = "Name is Missing")]
public string Name { get; set; }
}
}
public class HeEmailAddress
{
[JsonProperty("address")]
[Required]
[EmailAddress]
public string Address { get; set; }
}
#endregion
}
If I were to pass an obviously invalid JSON:
{"names":{"organizationNames":[{"user":"apple"}]}}
I was expecting DeserializeObject() to fail or throw an Error, but instead it simply assigns 'Name' to null.
var myJson = JsonConvert.DeserializeObject<T>(jsonFilter);
Where T is the instance of the class.
Any suggestion on how to perform such Validations?
You could use Newtonsoft.Json.Schema to validate the schema of any given Json.
For example, for the class structure you have defined, an equivalent Schema could be generated as
var generator = new JSchemaGenerator();
var schema = generator.Generate(typeof(QueryJson));
The Generated Schema is as follows
{
"definitions": {
"HeEmailAddress": {
"type": [
"object",
"null"
],
"properties": {
"address": {
"type": "string",
"format": "email"
}
},
"required": [
"address"
]
},
"HeName": {
"type": [
"object",
"null"
],
"properties": {
"organizationNames": {
"type": "array",
"items": {
"$ref": "#/definitions/HeOrganizationName"
}
}
},
"required": [
"organizationNames"
]
},
"HeOrganization": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": [
"string",
"null"
]
}
},
"required": [
"id"
]
},
"HeOrganizationName": {
"type": [
"object",
"null"
],
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
]
}
},
"type": "object",
"properties": {
"organization": {
"$ref": "#/definitions/HeOrganization"
},
"names": {
"$ref": "#/definitions/HeName"
},
"emails": {
"type": [
"array",
"null"
],
"items": {
"$ref": "#/definitions/HeEmailAddress"
}
}
},
"required": [
"organization",
"names",
"emails"
]
}
You could now use the Schema to validate your jsons. For example, for the sample invalid json provided in OP
var invalidJson = #"{""names"":{""organizationNames"":[{""user"":""apple""}]}}";
var jsonInstance = JObject.Parse(invalidJson);
bool valid = jsonInstance.IsValid(schema); // False

How do I sort a list based on its child object attributes?

I'm wondering if someone can elucidate a method to sort a list of objects based on a child object's attribute.
I'm working with the following model:
public class Content
{
public string Id { get; set; }
public List<ContentAttribute> Attributes { get; set; }
}
public class ContentAttribute
{
public string Value { get; set; }
public string Id { get; set; }
public string Name { get; set; }
}
Some sample data:
[
{
"Id": "123",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name1"
},
{
"Value": "ghi",
"Id": "2b",
"Name": "name2"
}
]
},
{
"Id": "456",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name2"
},
{
"Value": "def",
"Id": "2b",
"Name": "name3"
}
]
},
{
"Id": "789",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name1"
},
{
"Value": "def",
"Id": "2b",
"Name": "name2"
}
]
}
]
How can I sort the Content objects by the Value of a specific attribute Name? For example, I would like to sort the above data by the Value of 'name2',
meaning the result would be
[
{"Id" : "456"},
{"Id" : "789"},
{"Id" : "123"}
]
Any help is greatly appreciated. (Using c#).
If Attributes always has an element with name name2 and you want an exception if it doesn't then:
var sorted = contents.OrderBy(c => c.Attributes.First(a => a.Name == "name2").Value).ToList();
Or if name2 could be missing and it's not deal breaker then use FirstOrDefault
var sorted = contents.OrderBy(c => c.Attributes.FirstOrDefault(a => a.Name == "name2")?.Value).ToList();

Generate c# classes from json dynamically

I usually use json2csharp to generate json classes to c#. But I do have problem. My json is have dynamic depth like this
{
"kategori": [
{
"id": "1",
"namakategori": "Tips & Trick",
"parent_id": "0",
"children": [
{
"id": "348",
"namakategori": "Fotografi",
"parent_id": "1",
"children": []
},
{
"id": "370",
"namakategori": "Hacking",
"parent_id": "1",
"children": []
}
]
},
{
"id": "12",
"namakategori": "Aplikasi",
"parent_id": "0",
"children": [
{
"id": "13",
"namakategori": "Tools",
"parent_id": "12",
"children": [
{
"id": "14",
"namakategori": "Toolsorder",
"parent_id": "13",
"children":[]
},
]
},
]
},
]
}
So how do I generate json classes dynamically so it can be used for my json? In above example I have 3 depth. But if I go to different page maybe it have 4 or more depth.
You don't need to declere your classes dynamically. This should work:
public class Child
{
public string id { get; set; }
public string namakategori { get; set; }
public string parent_id { get; set; }
public List<Child> children { get; set; } // <-- See this
}
public class RootObj
{
public List<Child> kategori { set; get; }
}
To deserialize I'll use Json.Net
var res = JsonConvert.DeserializeObject<RootObj>(json);
You can always use the Newtonsoft.Json
For Instance,
JObject result = (JObject) JsonConvert.DeserializeObject(yourJsonDataHere);
var katObject = result.Property("kategori").Value;
and so on...
PS: Not sure if Newtonsoft.Json is supported on WP7.

Categories