Add anonymous or an object properties to JObject in C# - c#

I have following class
public class Customer{
public string name {get;set;}
public JObject properties {get;set;} = new JObject();
}
Now I am adding properties to customer properties
var customer = new Customer();
customer.properties["wow-123:test"] = new {
name = "Mark,
company = new {
name = "LLC",
address = new {
city= "London" } } }
In the end I want this to look like:
"properties": {
"wow-123:test": [
{
"name": "Mark",
"company": {
"name": "LLC",
"address ": {
"city": "London"
}
}
}
]
}
I keep getting error that it cannot convert it to Jtoken. If I change it to ToString then it is not in JSON format. How can I achieve the above?

First, you need to explicitly convert your anonymously typed object to a JToken:
customer.properties["wow-123:test"] = JToken.FromObject(new { ... });
However, since your example output shows that the contents of wow-123:test are an array (..."wow-123:test": [ { "name":...) , what you actually need might be
customer.properties["wow-123:test"] = new JArray(JToken.FromObject(new { ... } ));
which will create a single-element array containing your anonymously typed object.
fiddle

Related

How can I return a C# Object instead of array JSON

I have this code
return Ok(
new object[]
{
new { name = Dname, primaryLastName =DprimaryLastName, secondLastName= DsecondLastName,degrees= Ddegrees, roles= Droles, entityId = DentityId, enrollment = Denrollment, payrollNumber = DpayrollNumber, photo = Dphoto, groupsInfo = rt , birthDate = DbirthDate}
}
);
All variables values are string, except rt:
var rt = new Dictionary<string, string>();
foreach (DataTable table in dsgroupsinfo.Tables)
{
foreach (DataRow dr in table.Rows)
{
rt.Add("required", dr["requerido"].ToString());
rt.Add("optional", dr["opcional"].ToString());
}
}
My result from the service is this:
[
{
"name": "string",
"primaryLastName": "string",
"secondLastName": "string",
"degrees": "string",
"roles": "string",
"entityId": "string",
"enrollment": "string",
"payrollNumber": "string",
"photo": "string",
"groupsInfo": {
"required": "string",
"optional": "string"
},
"birthDate": "string"
}
]
how can I get a response like this:
{
"name": "string",
"primaryLastName": "string",
"secondaryLastName": "string",
"degrees": "string",
"roles": "string",
"entityId": "string",
"enrollment": "string",
"photo": "",
"groupsInfo": {
"required":["string"],
"optional": ["string"]
}
}
Please note there is no square brackets in the begining and the end, and inside groups info there are square brackets.
Hope you can help me, thanks.
Looks like you need to remove the outer array, and use a list for the dictionary value
var required = new List<string>>();
var optional = new List<string>>();
foreach (DataTable table in dsgroupsinfo.Tables)
{
foreach (DataRow dr in table.Rows)
{
required.Add(dr["requerido"].ToString());
optional.Add(dr["opcional"].ToString());
}
}
var rt = new Dictionary<string, List<string>>
{
{"required", required},
{"optional", optional},
};
return Ok(
new {
name = Dname,
primaryLastName = DprimaryLastName,
secondLastName = DsecondLastName,
degrees = Ddegrees,
roles = Droles,
entityId = DentityId,
enrollment = Denrollment,
payrollNumber = DpayrollNumber,
photo = Dphoto,
groupsInfo = rt,
birthDate = DbirthDate
}
);
Ideally you would use a proper object model, as the other answer has shown.
The main issue if that your service is returning an array, if that is not intended you should change that method so it returns an object.
If you know what you are returning, you could try to use Newtonsoft.Jsonto deserialize from a C# object.
Creating the C# class
Let's say that we have this class:
using Newtonsoft.Json;
// Naming the class Person, I assume it is a person.
public class Person
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("primaryLastName")]
public string PrimaryLastName { get; set; }
[JsonProperty("secondaryLastName")]
public string SecondaryLastName { get; set; }
[JsonProperty("degrees")]
public string Degrees { get; set; }
[JsonProperty("roles")]
public string Roles { get; set; }
[JsonProperty("entityId")]
public string EntityId { get; set; }
[JsonProperty("enrollment")]
public string Enrollment { get; set; }
[JsonProperty("photo")]
public string Photo { get; set; } // Is it a string?
[JsonProperty("groupsInfo")]
public GroupsInfo GroupInfo { get; set; }
[JsonProperty("birthDate")]
public string BirthDate { get; set; }
public class GroupsInfo
{
[JsonProperty("required")]
public string Required { get; set; }
[JsonProperty("optional")]
public string Optional { get; set; }
}
}
This class contains all the properties of the JSON file. The JsonProperty("PropertyName") attribute name allows the parser/serializer to recognize the keys when parsing and serializing the JSON file.
Declaring the class and serializing to JSON
From your service, you can use this class to create the JSON object like this:
Person person = new Person() {
Name = Dname,
PrimaryLastName = DprimaryLastName,
SecondaryLastName = DsecondLastName,
Degrees = Ddegrees,
Roles = Droles,
EntityId = DentityId,
Enrollment = Denrollment,
Photo = Dphoto,
GroupsInfo = new Person.GroupsInfo("optional", "required"), // Don't forget to add the constructor.
BirthDate = DbirthDate
};
And then, using the below line, you can serialize it to a string:
using Newtonsoft.Json;
...
string GetSerializedDataFromPerson(Person person)
{
return JsonConvert.SerializeObject(person, Formatting.Indented);
}
This can be sent from the service to the app, since it is now formatted as a JSON, or you can create a file that contains the formatted json content.
Parsing the JSON file to the C# class
To get your data, you would firstly fetch your JSON file content as string, from any source.
After that, you could use the following code:
using Newtonsoft.Json;
...
string json = /* Read file, get from server */;
Person person = JsonConvert.DeserializeObject<Person>(json);
System.Diagnostics.Debug.WriteLine($"First name {person.Name}");
// The above code will show the parsed person json name.
You can then mess with it to make it working as your expectations. Although, it seems like some parts of your JSON have to be reviewed, the design might not be the best.
Some keys like required or optional look like to be a bool, and is is not possible to return a string[] if the service returns a string.

Convert json string from one type to another with .net core c#

I am struggling to convert below input json to output json as this is what is the required format to call
hubspot api to submit a form. I am writing this using .net core within Azure function.
Input Json
{
"Email":"myemail#test.com",
"Phone":"12345678",
"Address":"address 1"
}
Output json
{
"fields": [
{
"name": "Email",
"value": "myemail#test.com"
},
{
"name": "Phone",
"value": "12345678"
},
{
"name": "Address",
"value": "address 1"
}
]
}
I converted the input json to dictionary using
IDictionary<string, string> dictionary = JsonConvert.DeserializeObject<IDictionary<string, string>>(inputJson);
but that gives me key value pair instead of name value pair.
I would like the output as detailed above.
Any help/example code would be highly appreciated.
You could create your own "NameValuePair" class/struct if you don't want "Key" as the field name:
public class FieldContainer
{
[JsonProperty("fields")]
public IEnumerable<NameValuePair> Fields { get; set; }
}
public struct NameValuePair
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
public NameValuePair(string name, string value)
{
Name = name;
Value = value;
}
}
And then do like you've already done, but converting the KeyValuePairs into your own struct:
var inJson = #"{
""Email"":""myemail#test.com"",
""Phone"":""12345678"",
""Address"":""address 1""
}";
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(inJson);
var container = new FieldContainer
{
Fields = dict.Select(pair => new NameValuePair(pair.Key, pair.Value))
};
var outJson = JsonConvert.SerializeObject(container);
See this fiddle for a demonstration.
Easiest way to do this would be to take the json and convert it to Dictionary<string, string>. Loop over each KeyValuePair and create a list of Fields using LINQ. Once you have the List of fields, create your RootObject.
public class RootObject
{
[JsonProperty("fields")]
public List<Field> Fields { get; set; }
}
public class Field
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
// Create a dictionary
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonStr);
// Create a list of Fields
List<Field> fields = dict.Select(x => new Field() { Name = x.Key, Value = x.Value }).ToList();
// Create the final Object.
RootObject rootObj = JsonConvert.SerializeObject(new RootObject() { Fields = fields });
Alternative solution, using JObject.Parse() to parse the original JSON, then iterate its Properties to create an array of JObjects with different names and values.
The resulting IEnumerable<JObject> is then converted to a JArray, used to create the final fields object.
var jObj = JObject.Parse(json);
var newObjects = jObj.Properties().Select(p => new JObject {
new JProperty("name", p.Name),
new JProperty("value", p.Value)});
var fields = new JObject() {
{ "fields", JArray.FromObject(newObjects)}
};
Console.WriteLine(fields);

How do I make a JSON array?

I want many of them but I don't how to make so many I can only make one just like this here:
[
{
"NAME1": "Max1"
}
]
But I want to make this:
[
{
"NAME1": "Max1"
},
{
"NAME2": "Max2"
},
{
"NAME3": "Max3"
},
{
"NAME4": "Max4"
}
]
How do I do it
Here is my code:
public void nxt_Click(object sender, EventArgs e)
{
List<Voc> _data = new List<Voc>();
_data.Add(new Voc()
{
NAME = textBox1.Text
});
string jger2 = JsonConvert.SerializeObject(_data.ToArray(), Formatting.Indented);
File.WriteAllText(#"D:\Users\Oxygen\Desktop\ss.json", jger2);
}
public class Voc
{
public string NAME { get; set; }
}
has anybody any ideas?
Below are a couple of ways to do this, demonstrated in this fiddle.
The first uses anonymous types, which are objects which don't have a real class, but are constructed by assigning values to properties. However, to use these you need to know the property names at compile time; so this will only work if you know exactly how many names you'll have in your array. e.g.
var data = new object[] {
new {Name1 = textBox1.Text}
,new {Name2 = textBox2.Text}
,new {Name3 = textBox3.Text}
,new {Name4 = textBox4.Text}
};
Another approach is to use a dictionary, which can be populated with name value pairs at runtime, then you can convert these to JSON. E.g.
var textBoxes = new [] {textBox1, textBox2, textBox3, textBox4};
var dict = new Dictionary<string,string>();
for (var i = 0; i< textBoxes.Length; i++)
{
dict.Add(string.Format("Name{0}", i), textBoxes[i].Text );
}
However
I would strongly advise against these methods; or rather this approach. JSON is designed to be made up of key-value pairs. They keys should be known, whilst the values can change. That means that if you have 4 different values for a name instead of holding 4 different names, you hold those values against that name; e.g.
{"Name": ["Max1","Max2","Max3","Max4"]}
...with the number of the element being defined by the array's index.
The C# for that looks like this:
SomeClass data = GetValues();
//...
public class SomeClass
{
public IEnumerable<string> Name {get;private set;}
//or: public string[] Name {get;private set;}
//...
}
If you really need to store the different names, those should be stored as values against the name key; e.g.
[
{"Name": "Name1", "Value": "Max1"}
,{"Name": "Name2", "Value": "Max2"}
,{"Name": "Name3", "Value": "Max3"}
,{"Name": "Name4", "Value": "Max4"}
]
The C# for that looks like this:
IEnumerable<SomeClass> data = GetValues();
//or: SomeClass[] data = GetValues();
//...
public class SomeClass
{
public string Name {get;private set;}
public string Value {get;private set;}
//...
}
 
Full Code
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
//setup our test data
var textBox1 = new TextBox("Max1");
var textBox2 = new TextBox("Max2");
var textBox3 = new TextBox("Max3");
var textBox4 = new TextBox("Max4");
//demo using anonymous objects (NB: property names must be known at compile time)
var data = new object[] {
new {Name1 = textBox1.Text}
,new {Name2 = textBox2.Text}
,new {Name3 = textBox3.Text}
,new {Name4 = textBox4.Text}
};
Console.WriteLine( JsonConvert.SerializeObject(data, Formatting.Indented));
//demo using a dictionary
var textBoxes = new [] {textBox1, textBox2, textBox3, textBox4};
var dict = new Dictionary<string,string>();
for (var i = 0; i< textBoxes.Length; i++)
{
dict.Add(string.Format("Name{0}", i+1), textBoxes[i].Text );
}
Console.WriteLine("[" + string.Join(",", dict.Select( e => string.Format("{{\"{0}\": \"{1}\"}}", e.Key.Replace("\"","\"\""), e.Value.Replace("\"","\"\"") ) )) + "]"); //based on https://stackoverflow.com/questions/5597349/how-do-i-convert-a-dictionary-to-a-json-string-in-c/5597628#5597628
}
}
//dummy class
public class TextBox
{
public TextBox(string text){Text = text;}
public string Text{get;private set;}
}
First of all, your Array is poorly formatted.
It should be:
{
"NAMES": [
{
"NAME": "Max1"
},
{
"NAME": "Max2"
},
{
"NAME": "Max3"
},
{
"NAME": "Max4"
}
]
}
Run that through json2Csharp.com and it will generate the following:
public class NAME
{
public string NAME { get; set; }
}
public class RootObject //Rename this
{
public List<NAME> NAMES { get; set; }
}
Which you should be able to serialize and deserialize using almost any C# JSON library.

Create Serialize JSON List Type object from c# class

Dear All I am using C# Class and make the json object but how it call it.
and show the json object I am show the code please help me.
Here I am create a class
public class Contacts
{
public List<PhoneMobile> phoneMobiles { get; set; }
public List<PhoneLandline> phoneLandlines { get; set; }
public List<Email> emails { get; set; }
}
public class PhoneMobile
{
public string phoneMobile { get; set; }
}
Here i am use the class like this
contacts = new Contacts
{
phoneMobiles = new List<PhoneMobile>
{
},
phoneLandlines = new List<PhoneLandline>(),
emails = new List<Email>(),
}
I want SerializeObject Like This objects give how to put a value and make it.
"contacts": {
"phoneMobiles": [
{
"phoneMobile": "8103267511"
}
],
"phoneLandlines": [
{
"phoneLandLineNumber": "8103267511"
}
],
"emails": [
{
"email": "testing#gmail.com"
}
]
},
"contactPerson": [
{
"personName": "TEST KARKHANA",
"owner": "null",
"email": "sanjeet.kumar#mponline.gov.in",
"phone": "8602865989"
}
],
How To Make It Please Help
Use Json.Net library, you can download it from Nuget.
Try this
var contactCollection = new Contacts
{
phoneMobiles = new List<PhoneMobile>
{
new PhoneMobile { phoneMobile = "8103267511" }
},
phoneLandlines = new List<PhoneLandline>()
{
new PhoneLandline { phoneLandLineNumber = "8103267511" }
},
emails = new List<Email>()
{
new Email { email = "testing#gmail.com" }
}
};
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(contacts);
It will serialize object to json except contactPerson section
If you need serialize object with root name contacts then try
var collectionWrapper = new {
contacts = contactCollection
};
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(collectionWrapper);
then the result will be like:
{"contacts":{"phoneMobiles":[{"phoneMobile":"8103267511"}], "phoneLandlines":[{"phoneLandLineNumber":"8103267511"}], "emails":[{"email":"testing#gmail.com"}]}}

Dynamically Select Required JSON information

I need to deserialize some JSON but the problem is that all of my JSON objects don't have the exact same format.
Here is an example of the JSON that I have to deserialize :
[
{
"Player_Name": "Zlatan Ibrahimovic",
"Country": "Sweeden",
"Other_Informations": {
"Information1": [
]
},
},
{
"Player_Name": "Pavel Nedved",
"Country": "Czech Republic",
"Personal_Honours":
{
"Ballon_DOr": "One",
},
"Other_Informations": {
"Information1": [
]
},
},
{
"Player_Name": "Zinedine Zidane",
"Country": "Sweeden",
"Other_Informations": {
"Information1": [
{
"name": "example",
}
]
},
}
]
As you can see, some fields appear only for some objects for example "Personal_Honours".
I need to deserialize the JSON into this class :
public class PlayerData
{
public string Name { get; set; }
public string BallonDor {get; set; }
public string Information1{ get; set; }
public string Country{ get; set; }
}
I use this method which is really long and blocks my app :
(In this exmple I use Json that comes frome a textfile but usually I have to make a REST request..)
StreamReader reader = File.OpenText("TextFile1.txt");
List<PlayerData> DataList;
dynamic value= JsonConvert
.DeserializeObject<dynamic>(reader.ReadToEnd());
DataList = new List<PlayerData>();
foreach (dynamic data in value)
{
if (data.Personal_Honours == null)
{
if (data.Other_Informations.Information1 == null)
{
DataList.Add(new PlayerData
{
Name = data.Player_Name,
Country = data.Country,
});
}
else
{
DataList.Add(new PlayerData
{
Name = data.Player_Name,
Country = data.Country,
Information1 = data.Informations.Information1
});
}
}
else
{
if (data.Other_Informations.Information1 == null)
{
DataList.Add(new PlayerData
{
Name = data.Player_Name,
Country = data.Country,
BallonDor = data.Personal_Honours.Ballon_DOr
});
}
else
{
DataList.Add(new PlayerData
{
Name = data.Player_Name,
Country = data.Country,
BallonDor = data.Personal_Honours.Ballon_DOr,
Information1 = data.Informations.Information1
});
}
}
}
This method is working but it is not efficient and blocks my UI.
How can I do to create a new "PlayerData" object without having all of those 'else if' statements ?
Thank you !
P.S : The question is different from this one Filter JSon Information
EDIT :
Here is how I got the RunTimeBinderExcepetion :
List<PlayerData> datalist = new List<PlayerData>();
foreach (dynamic pl in timeline)
{
datalist.Add(new PlayerData
{
Name = pl.Player_Name ,
Country = pl.Country ,
BallonDor = pl.Personal_Honours.Ballon_Dor,
Information1 = pl.Other_Informations.Information1.name
});
}
You got exception because some data doesn't have Personal_Honours property for example. Then you tried to access Ballon_Dor property from a null reference which trigger the exception. This way will work for sample JSON you posted :
List<PlayerData> datalist = new List<PlayerData>();
foreach (dynamic pl in timeline)
{
//object initialization is done later just for the sake of easier debugging
//...so we can spot unexpected data which cause exception easily
var Name = pl.Player_Name;
var Country = pl.Country;
var BallonDor = pl.Personal_Honours != null ? pl.Personal_Honours.Ballon_Dor : null;
var Information1 = pl.Other_Informations.Information1.Count > 0 ?
pl.Other_Informations.Information1[0].name :
null;
datalist.Add(new PlayerData
{
Name = Name ,
Country = Country ,
BallonDor = BallonDor,
Information1 = Information1
});
}
...but above approach is still error prone depending on how consistent is the JSON string we have. More robust approach is maybe to have model classes to map JSON string as suggested by #L.B in comment.

Categories

Resources