C# Json.NET Camel Case Complex Object - c#

I'm trying to serialize an object as camelCase and I'm finding that only the objects at the root level are correctly camelCased. Everything below the root level is coming as PascalCase. I'm writing a console application using Json.NET 12.0.3 and .NET Framework 4.0.
public class Deal
{
public string Id { get; set; }
public string Name { get; set; }
public List<PublicId> PublicIds { get; set; }
}
public class PublicId
{
public string IdType { get; set; }
public string Value { get; set; }
}
To serialize I'm using:
var json = JsonConvert.SerializeObject(deal, Formatting.Indented, new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-dd",
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
The result json looks like:
{
"id": null,
"name": "Deal 1",
"publicIds": [
{
"IdType": "ID1",
"Value": "A12"
},
{
"IdType": "ID2",
"Value": "B12"
}
]
}
As you can see the values for IdType and Value are not correctly serialied in camelCase but rather are serialized in PascalCase. There are situations where I'll need to change the serialization between the default PascalCase and camelCase so I won't be able to use JsonProperty annotations to force camelCase during serialization. Additionally I'd like to stick to Json.NET as the only json library for my project.
Is there a clean way to get what I'm looking for?

Firstly I noticed that your Deal class does not initialize PublicIds. In that case the code should actually throw an error.
However, your code that specifies the contract solver CamelCasePropertyNamesContractResolver is correct.
The following is a console code that seems to return proper JSON value.
public class Deal
{
public Deal()
{
PublicIds = new List<PublicId>();
}
public string Id { get; set; }
public string Name { get; set; }
public List<PublicId> PublicIds { get; set; }
}
public class PublicId
{
public string IdType { get; set; }
public string Value { get; set; }
}
Then in the console if the try the code below it seems to yield the desired result.
public static void Main()
{
var deal = new Deal();
deal.Name = "Deal 1";
deal.PublicIds.Add(new PublicId { IdType = "ID1", Value = "A12" });
deal.PublicIds.Add(new PublicId { IdType= "ID2", Value= "B12"});
var json = JsonConvert.SerializeObject(deal, Formatting.Indented, new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-dd",
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
Console.WriteLine(json);
Console.ReadLine();
}
Output by the code:
{
"id": null,
"name": "Deal 1",
"publicIds": [
{
"idType": "ID1",
"value": "A12"
},
{
"idType": "ID2",
"value": "B12"
}
]
}

Related

Working with Irregular nodes/elements in json response from an API

I have a situation while working with a JSON response from an API. To give a background, I am consuming an API from a source using a REST API using 3.5 .net framework.
Below is the part of the JSON output and I am kind of struggling to use it.
a)
"value": {
"Description": "Total Calculated things",
"2018": "5,820,456 ",
"2019": "2,957,447 "
}
The last 2 elements are dynamic, those are tend to change in API response. I was expecting the format like I have mentioned below, but at this point of given time the source provider is not able to change it as the API is used in many other different programs. And Changing the things in the source API will make other program owners to change.
b)
"value": {
"Description": "Total Calculated EQUITY AND LIABILITIES",
"YearData": [ {
"Data": "5,820,456",
"Year": "2018"
},
{
"Data": "2,957,447 ",
"Year": "2019"
} ]
}
Is there any way to overcome such thing> Any way to convert a to b?
EDIT
#Xerillio , Thanks . How can I achieve the same using below JSON format.
var json = #"
{
""entityData"": [
{
""name"": ""Statement of Comprehensive Income"",
""subattrOutput"": [
{
""name"": ""Sales"",
""subattrOutput"": [],
""value"": {
""Description"": ""Sales "",
""2018"": ""8,704,888 "",
""2019"": ""4,760,717 ""
},
""score"": ""99.5"",
""valuetype"": ""object""
},
{
""name"": ""Cost of goods sold"",
""subattrOutput"": [],
""value"": {
""Description"": ""Cost of sales "",
""2018"": ""(6,791,489) "",
""2019"": ""(3,502,785) ""
},
""score"": ""99.75"",
""valuetype"": ""object""
}
],
""value"": null,
""score"": ""98.63"",
""valuetype"": ""object""
}
]
}";
I wish this was more easy, but i just got it here:
class Program
{
static async Task Main(string[] args)
{
string json1 = #"{""value"": {""Description"": ""Total Calculated things"",""2018"": ""5,820,456 "",""2019"": ""2,957,447 ""}}";
string json2 = #"{""value"": {""Description"": ""Total Calculated EQUITY AND LIABILITIES"",""YearData"": [ {""Data"": ""5,820,456"",""Year"": ""2018""},{""Data"": ""2,957,447 "",""Year"": ""2019""} ]}}";
var obj1 = JsonConvert.DeserializeObject<ObjectResult>(json1);
var obj2 = JsonConvert.DeserializeObject<ObjectResult>(json2);
var res1 = CastObject<Result1>(obj1.Value.ToString());
var res2 = CastObject<Result2>(obj2.Value.ToString());
var invalidRes1 = CastObject<Result1>(obj2.Value.ToString());
var invalidRes2 = CastObject<Result2>(obj1.Value.ToString());
Console.WriteLine(res1);
Console.WriteLine(res2);
}
public static T CastObject<T>(string obj)
{
return !TryCastObject(obj, out T result) ? default : result;
}
public static bool TryCastObject<TOut>(string objToCast, out TOut obj)
{
try
{
obj = JsonConvert.DeserializeObject<TOut>(objToCast);
return true;
}
catch
{
obj = default;
return false;
}
}
}
public class ObjectResult
{
public object Value { get; set; }
}
public class Result1
{
[JsonProperty(PropertyName = "description")] public string Description { get; set; }
[JsonProperty(PropertyName = "2018")] public string _2018 { get; set; }
[JsonProperty(PropertyName = "2019")] public string _2019 { get; set; }
}
public class Result2
{
[JsonProperty(PropertyName = "Description")] public string Description { get; set; }
[JsonProperty(PropertyName = "YearData")] public List<YearData> YearData { get; set; }
}
public class YearData
{
[JsonProperty(PropertyName = "Data")] public string Data { get; set; }
[JsonProperty(PropertyName = "Year")] public string Year { get; set; }
}
It is A LOT of work and sincerely, as there more nodes in the json i think that using JObject is the best option, and you will have to do a deserealization in more than 1 step :(
Depending on how large the JSON structure is you could deserialize it into a Dictionary and manually map it to the proper format:
var json = #"
{
""value"": {
""Description"": ""Total Calculated things"",
""2018"": ""5,820,456 "",
""2019"": ""2,957,447 ""
}
}";
var badObj = JsonSerializer.Deserialize<BadFormat>(json);
var result = new WrapperType
{
Value = new ProperlyFormattedType()
};
foreach (var pair in badObj.Value)
{
if (pair.Key == "Description")
{
result.Value.Description = pair.Value;
}
else if (int.TryParse(pair.Key, out int _))
{
result.Value.YearData
.Add(new DatedValues
{
Year = pair.Key,
Data = pair.Value
});
}
}
// Data models...
public class BadFormat
{
[JsonPropertyName("value")]
public Dictionary<string, string> Value { get; set; }
}
public class WrapperType
{
public ProperlyFormattedType Value { get; set; }
}
public class ProperlyFormattedType
{
public string Description { get; set; }
public List<DatedValues> YearData { get; set; } = new List<DatedValues>();
}
public class DatedValues
{
public string Year { get; set; }
public string Data { get; set; }
}
See an example fiddle here.

How to bind property name of the data model object in .net core

I have created a data model class and have another created a property of another class type inside that.
Ex:
public class Properties
{
public string PropertyName { get; set; }
public TypeExt Property { get; set; }
}
public class TypeExt
{
public string DataType { get; set; }
public string DataTypeExt { get; set; }
public string Type { get; set; }
}
Now, when i bind the values, everything works fine except that i need the PropertyName value to come as the Label for Property so that the final Json becomes like this.
{
"Properties":[
{
"Test1Property":{
"DataType":"Unsigned integer ",
"DataTypeExt":"64bit",
"Type":"PM"
}
},
{
"Test2Propert":{
"DataType":"Integer ",
"DataTypeExt":"64bit",
"Type":"PM"
}
}
]
}
One way to get it so you get the PropertyName to be a key is by using a Dictionary as part of your model.
var properties = new Dictionary<string, TypeExt>();
var test1Property = new TypeExt { Type = "PM", DataType = "Integer", DataTypeExt = "64bit" };
var test2Property = new TypeExt { Type = "PM", DataType = "Unsigned Integer", DataTypeExt = "64bit" };
properties.Add("Test1Property", test1Property);
properties.Add("Test2Property", test2Property);
What this results in when serialized is the following. It is a slightly different JSON than what you have above though. Notice that it is no longer an "array-of-objects", but an object that contains properties, each of which are the dictionary keys.
{
"Test1Property" : {
"Type": "PM",
"DataType": "Integer",
"DataTypeExt": "64bit"
},
"Test2Property" : {
"Type": "PM",
"DataType": "Unsigned Integer",
"DataTypeExt": "64bit"
}
}

Json.net ignore null values of child objects

I am new into json.net, so any help would be appreciated.
I am using the net 2.0 version of json.net, because i need to integrate it in Unity3d engine Suggested answer (using nullvaluehandling) just don't work! Should i consider this as restiction of the oldest version?
So, a have an object like this:
Object ()
{
ChildObject ChildObject1;
ChildObject ChildObject2;
}
ChildObject ()
{
Property1;
Property2;
}
I want json.net to serialize only not null properties of all objects, including child objects. So if i instatiate only property1 of ChildObject1 and property2 of ChildObject2, the string from JsonConvert will be like this:
{
"ChildObject1":
{
"Property1": "10"
},
"ChildObject1":
{
"Property2":"20"
}
}
But default behaviour creates string like this:
{
"ChildObject1":
{
"Property1": "10",
"Property2": "null"
},
"ChildObject2":
{
"Property1": "null,
"Property2":"20"
}
}
I know about NullValueHandling, but it is not working corretly in my case! It ignore only null properties of the parent object (object that we are serializing), but if this parent object has some childs, it will not ignore null properties of this child objects. My situation is different.
If even one property of a child object is not null, it serialize it to a string with one not-null property and others null.
UPD example of my code:
i have nested classes
My object is like this:
public class SendedMessage
{
public List<Answer> Answers { get; set; }
public AnswerItem Etalon {get; set;}
}
public class Answer ()
{
public AnswerItem Item { get; set; }
}
public class AnswerItem ()
{
public string ID { get; set; }
public bool Result { get; set; }
public int Number { get; set; }
}
i instatiate a SendedMessage object like this:
new SendedMessage x;
x.Etalon = new AnswerItem();
x.Etalon.Result = true;
than i use
string ignored = JsonConvert.SerializeObject(x,
Formatting.Indented,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
and it make this string:
{ "Etalon": {"ID" = "null", "Result" = "false", Number" = "null"}}
so it really ignore the null object Answers (a List), but do not ignore the null properties of a child objects.
Thanks for help!
use this :
string ignored = sonConvert.SerializeObject(movie,
Formatting.Indented,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
here is the example:
public class Movie
{
public string Name { get; set; }
public string Description { get; set; }
public string Classification { get; set; }
public string Studio { get; set; }
public DateTime? ReleaseDate { get; set; }
public List<string> ReleaseCountries { get; set; }
}
static void Main(string[] args)
{
Movie movie = new Movie();
movie.Name = "Bad Boys III";
movie.Description = "It's no Bad Boys";
string included = JsonConvert.SerializeObject(movie,
Formatting.Indented,new JsonSerializerSettings { });
// {
// "Name": "Bad Boys III",
// "Description": "It's no Bad Boys",
// "Classification": null,
// "Studio": null,
// "ReleaseDate": null,
// "ReleaseCountries": null
// }
string ignored = JsonConvert.SerializeObject(movie,
Formatting.Indented,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
// {
// "Name": "Bad Boys III",
// "Description": "It's no Bad Boys"
// }
}

Json parse sub-collection in c#

How can I do JSON in C# like the data below ?
{
"Aliases": [ "teddy", "freddy", "eddy", "Betty" ],
"Name":"reacher gilt",
"Address":"100 East Way",
"Age":74,
"Bars": {
"items": [
{
"Sub_Property1":"beep",
"Sub_Property2":"boop"
},
{
"Sub_Property1":"meep",
"Sub_Property2":"moop"
},
{
"Sub_Property1":"feep",
"Sub_Property2":"foop"
}
]
}
}
Actually my problem is inside the sub-collection. I saw someone did something
like this
person.Bars.Add("items",
new List<BarClass>(new[]{
new BarClass("beep","boop"),
new BarClass("meep","moop"),
new BarClass("feep","foop"),
}));
So, I have to add new BarClass("beep","boop"), but I need to do something
like this
String [] no1 = {1,2,3}
String [] no2 = {4,5,6}
person.Bars.Add("items",
new List<BarClass>(new[]{
for ()
{
new BarClass(no1[i],no2[i])
}
}));
How can i do this? Thanks and please help..
To read the JSON
The best way to read the whole JSON is to Deserialize it to a native C# object. If you do not already have the classes with your, you can create it in Visual Studio as
Copy your JSON text
Create a new empty class file in VS
Edit > Paste Special > Paste JSON As Classes
Here are the classes
public class Person
{
public string[] Aliases { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
public Bars Bars { get; set; }
}
public class Bars
{
public Item[] items { get; set; }
}
public class Item
{
public string Sub_Property1 { get; set; }
public string Sub_Property2 { get; set; }
}
Now you can use some .NET JSON library to deserialize. JSON.Net aka Newtonsoft JSON is a great library. You get get it from NuGet as well.
Then it's pretty easy to get the C# object from the JSON
//using Newtonsoft.Json;
var jsonString = File.ReadAllText(#"C:\YourDirectory\person.json");
var person = JsonConvert.DeserializeObject<Person>(jsonString);
If you want to read the sub-collection only, you can rather use Linq-to-JSON to read the items directly, like this
//using Newtonsoft.Json.Linq;
var jObject = JObject.Parse(jsonString);
List<Item> details = jObject["Bars"]["items"].ToObject<List<Item>>();
To create the JSON
You first need to create the object, then Serialize to JSON
string[] subProperties1 = new string[] { "1", "2", "3" };
string[] subProperties2 = new string[] { "4", "5", "6" };
Person person = new Person { Name = "Johny", Age = 7, Address = "Earth", Aliases = new string[] { "Sony", "Monty" } };
person.Bars = new Bars {
items = subProperties1.Zip(subProperties2,
(prop1, prop2) => new Item { Sub_Property1 = prop1, Sub_Property2 = prop2 })
.ToArray() };
var json = JsonConvert.SerializeObject(person);
To create the items from your existing string arrays, I have used IEnumerable.Zip function from Linq. You can read about them here.
This is the created JSON data
{
"Aliases": [ "Sony", "Monty" ],
"Name": "Johny",
"Address": "Earth",
"Age": 7,
"Bars": {
"items": [
{
"Sub_Property1": "1",
"Sub_Property2": "4"
},
{
"Sub_Property1": "2",
"Sub_Property2": "5"
},
{
"Sub_Property1": "3",
"Sub_Property2": "6"
}
]
}
}
You should create some classes
public class Person
{
public string Name {get;set;}
public string Address{get;set;}
public int Age {get;set;}
public Header {get;set;}
}
public class Header
{
public Detail[] Details {get;set;}
}
public class Detail
{
public string Sub1 {get;set;}
public string Sub2 {get;set;}
}
Create instance from Person class and initialize to instance after than
JavaScriptSerializer serializer =new JavaScriptSerializer();
var result=serializer.Serialize(instanceOfPerson);
"result" is json data
Assuming that you mean you want to create JSON string, you need to create those classes and use something like Newtonsoft JSON.net:
public class Item
{
public string Sub_Property1 { get; set; }
public string Sub_Property2 { get; set; }
}
public class Bars
{
public List<Item> items { get; set; }
}
public class Person
{
public List<string> Aliases { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
public Bars Bars { get; set; }
}
Please read the documentation here: http://www.newtonsoft.com/json/help/html/Introduction.htm

How to get the values from list of objects in c#

I have Called a Json Web Service and got the result in c#.The Json Web service data is available in format:
{
"Count": 9862,
"Items": [
{
"Admin": {
"S": "false"
},
"UserId": {
"S": "e9633477-978e-4956-ab34-cc4b8bbe4adf"
},
"Age": {
"N": "76.24807963806055"
},
"Promoted": {
"S": "true"
},
"UserName": {
"S": "e9633477"
},
"Registered": {
"S": "true"
}
},
{
"Admin": {
"S": "false"
},
"UserId": {
"S": "acf3eff7-36d6-4c3f-81dd-76f3a8071bcf"
},
"Age": {
"N": "64.79224276370684"
},
"Promoted": {
"S": "true"
},
"UserName": {
"S": "acf3eff7"
},
"Registered": {
"S": "true"
}
},
I have got the Response like this in c#:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:8000/userdetails");
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
after finally successfully get the response i have got all the Data in string. and then parse this string in list of objects .Now I have list of objects where it showing the count in debugging.Now I want to access the values like UserId:acf3eff7-36d6-4c3f-81dd-76f3a8071bcf like properties.I dont know how to do it.Please help me and any help will be appreciated.
You can use the following code to get the values from json as:
JObject obj = JObject.Parse(json);
int count = (int)obj["Count"];
var Items = obj["Items"];
foreach (var item in Items)
var admin = item["Admin"];
Quick and dirty way:
//deserialize your string json using json.net
dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
//get value of UserId in first Item
var UserId = jsonObj["Items"][0]["UserId"]["S"];
//OR get the value of UserId for each Item in Items
//foreach(dynamic item in jsonObj["Items"])
//item["UserId"]["S"];
Advice is to use c# objects as mentioned by #yousuf
To be able to access Json property like common C# object property, you need to deserialize json string to strongly typed object (you can use, for example, JSON.NET to do deserialization).
Another handy tool is http://json2csharp.com/. Paste your Json there then you can generate classes definitions that suitable to map the Json automatically :
//RootObject class definition generated using json2csharp.com
//the rest of class definition removed for brevity.
public class RootObject
{
public int Count { get; set; }
public List<Item> Items { get; set; }
}
........
........
//in main method
var jsonString = .....;
//deserialize json to strongly-typed object
RootObject result = JsonConvert.DeserializeObject<RootObject>(jsonString);
foreach(var item in result.Items)
{
//then you can access Json property like common object property
Console.WriteLine(item.UserId.S);
}
you are deserializing string to c# object. you will need to create object that reperesents the json .
For example -
public class Admin
{
public string S { get; set; }
}
public class UserId
{
public string S { get; set; }
}
public class Age
{
public string N { get; set; }
}
public class Promoted
{
public string S { get; set; }
}
public class UserName
{
public string S { get; set; }
}
public class Registered
{
public string S { get; set; }
}
public class RootObject
{
public Admin Admin { get; set; }
public UserId UserId { get; set; }
public Age Age { get; set; }
public Promoted Promoted { get; set; }
public UserName UserName { get; set; }
public Registered Registered { get; set; }
}
Then deserialize json string to object using jsonSerializer
JavaScriptSerializer serializer = new JavaScriptSerializer();
var result =
(RootObject)serializer .DeserializeObject("Json String")
string json = #"{
""Name"": ""Apple"",
""Expiry"": new Date(1230422400000),
""Price"": 3.99,
""Sizes"": [
""Small"",
""Medium"",
""Large""
]
}";
JObject o = JObject.Parse(json);
//This will be "Apple"
string name = (string)o["Name"];

Categories

Resources