How can i convert JObject to object in C#? - c#

I have a JObject such as :
JObject obj = new JObject();
obj.Add(new JProperty("Name","Olivier"));
obj.Add(new JProperty("Surname","Big"));
obj.Add(new JProperty("FatherName","Johnatan"));
I want to convert obj above to object
If I use the this code below
var result1 = Newtonsoft.Json.JsonConvert.DeserializeObject<object>(obj.ToString());
the result is like this
But the result that wanted is like below
var TheResultIWant = new { Name = "Olivier", Surname = "Big", FatherName = "Johnatan" };
Is there any kind of way I can obtain the object like the second image. I cannot code like it because I don't know the property name.

Well, you could use method DeserializeAnonymousType for that:
JObject obj = new JObject();
obj.Add(new JProperty("Name", "Olivier"));
obj.Add(new JProperty("Surname", "Big"));
obj.Add(new JProperty("FatherName", "Johnatan"));
var result = new
{
Name = "",
Surname = "",
FatherName = ""
};
result = JsonConvert.DeserializeAnonymousType(obj.ToString(), result);
Another option is to use dynamic and third option which is by far most used is to create your own type and use it:
public class Person
{
public string Name { get; set; }
...
}
Person result = JsonConvert.DeserializeObject<Person>(obj.ToString());

A JObject is an already deserialized object. It can be used as a dynamic object so there's no need to serialize to a string and get back another object.
dynamic TheResultIWant = obj;
var name=TheResultIWant.Name;
It's already possible to access properties by key, like a dictionary:
var name=obj["Name"];
This returns a JToken. If the type of the value is known, Value< T> or Values<T> can be used to retrieve it:
var name=obj["Name"].Value<string>();

Related

.NET 6 “core” Create Dynamic Object containing List<MyOtherDynamicListObject> [duplicate]

For some of my unit tests I want the ability to build up particular JSON values (record albums in this case) that can be used as input for the system under test.
I have the following code:
var jsonObject = new JObject();
jsonObject.Add("Date", DateTime.Now);
jsonObject.Add("Album", "Me Against The World");
jsonObject.Add("Year", 1995);
jsonObject.Add("Artist", "2Pac");
This works fine, but I have never really like the "magic string" syntax and would prefer something closer to the expando-property syntax in JavaScript like this:
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Well, how about:
dynamic jsonObject = new JObject();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against the world";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
You can use the JObject.Parse operation and simply supply single quote delimited JSON text.
JObject o = JObject.Parse(#"{
'CPU': 'Intel',
'Drives': [
'DVD read/writer',
'500 gigabyte hard drive'
]
}");
This has the nice benefit of actually being JSON and so it reads as JSON.
Or you have test data that is dynamic you can use JObject.FromObject operation and supply a inline object.
JObject o = JObject.FromObject(new
{
channel = new
{
title = "James Newton-King",
link = "http://james.newtonking.com",
description = "James Newton-King's blog.",
item =
from p in posts
orderby p.Title
select new
{
title = p.Title,
description = p.Description,
link = p.Link,
category = p.Categories
}
}
});
Json.net documentation for serialization
Neither dynamic, nor JObject.FromObject solution works when you have JSON properties that are not valid C# variable names e.g. "#odata.etag". I prefer the indexer initializer syntax in my test cases:
JObject jsonObject = new JObject
{
["Date"] = DateTime.Now,
["Album"] = "Me Against The World",
["Year"] = 1995,
["Artist"] = "2Pac"
};
Having separate set of enclosing symbols for initializing JObject and for adding properties to it makes the index initializers more readable than classic object initializers, especially in case of compound JSON objects as below:
JObject jsonObject = new JObject
{
["Date"] = DateTime.Now,
["Album"] = "Me Against The World",
["Year"] = 1995,
["Artist"] = new JObject
{
["Name"] = "2Pac",
["Age"] = 28
}
};
With object initializer syntax, the above initialization would be:
JObject jsonObject = new JObject
{
{ "Date", DateTime.Now },
{ "Album", "Me Against The World" },
{ "Year", 1995 },
{ "Artist", new JObject
{
{ "Name", "2Pac" },
{ "Age", 28 }
}
}
};
There are some environment where you cannot use dynamic (e.g. Xamarin.iOS) or cases in where you just look for an alternative to the previous valid answers.
In these cases you can do:
using Newtonsoft.Json.Linq;
JObject jsonObject =
new JObject(
new JProperty("Date", DateTime.Now),
new JProperty("Album", "Me Against The World"),
new JProperty("Year", "James 2Pac-King's blog."),
new JProperty("Artist", "2Pac")
)
More documentation here:
http://www.newtonsoft.com/json/help/html/CreatingLINQtoJSON.htm
Sooner or later you will have property with a special character. e.g. Create-Date. The hyphen won't be allowed in property name. This will break your code. In such scenario, You can either use index or combination of index and property.
dynamic jsonObject = new JObject();
jsonObject["Create-Date"] = DateTime.Now; //<-Index use
jsonObject.Album = "Me Against the world"; //<- Property use
jsonObject["Create-Year"] = 1995; //<-Index use
jsonObject.Artist = "2Pac"; //<-Property use
Simple way of creating newtonsoft JObject from Properties.
This is a Sample User Properties
public class User
{
public string Name;
public string MobileNo;
public string Address;
}
and i want this property in newtonsoft JObject is:
JObject obj = JObject.FromObject(new User()
{
Name = "Manjunath",
MobileNo = "9876543210",
Address = "Mumbai, Maharashtra, India",
});
Output will be like this:
{"Name":"Manjunath","MobileNo":"9876543210","Address":"Mumbai, Maharashtra, India"}
May I suggest using the nameof expression combined with a model for the structure you're trying to build?
Example:
record RecordAlbum(string Album, string Artist, int Year);
var jsonObject = new JObject
{
{ nameof(RecordAlbum.Album), "Me Against The World" },
{ nameof(RecordAlbum.Artist), "2Pac" },
{ nameof(RecordAlbum.Year), 1995 }
};
As an added benefit to removing the "magic string" aspect - this also will give you a little bit of refactor-ability. You can easily rename any given property name for the record and it should update the value returned by the nameof() expression.
You can use Newtonsoft library and use it as follows
using Newtonsoft.Json;
public class jb
{
public DateTime Date { set; get; }
public string Artist { set; get; }
public int Year { set; get; }
public string album { set; get; }
}
var jsonObject = new jb();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
string sJSON = oSerializer.Serialize(jsonObject );

Deserialized object other than original serialized object

I am using ASP Net Core 2.2
I seralize this dynamic object
var stuff1 = new
{
Name = "John",
Surname = "Smith",
Addresses = new[] {
new { City = "New York", State = "NY"},
new { City = "Milano", State = "IT" }
};
var stuff1Serialized = JsonConvert.SerializeObject(stuff1)
This is the serialized object:
{"Name":"John","Surname":"Smith"}
Now, I get this string and I deserialized it
dynamic stuff1Deserialized = JsonConvert.DeserializeObject(stuff1Serialized);
I expect that sutff1 and stuff1Deseralized has the same strucure, but they are different, why?
In Immediate window:
stuff1.name
"Jhon"
stuff1Deserialized.Name
{John}
First: '((Newtonsoft.Json.Linq.JToken)stuff1Deserialized.Name).First' threw an exception of type 'System.InvalidOperationException'
HasValues: false
Last: '((Newtonsoft.Json.Linq.JToken)stuff1Deserialized.Name).Last' threw an exception of type 'System.InvalidOperationException'
Next: null
Parent: {"Name": "John"}
Path: "Name"
Previous: null
Root: {{
"Name": "John",
"Surname": "Smith"
}}
Type: String
Value: "John"
Results View: Expanding the Results View will enumerate the IEnumerable
I use the object with this simple DotLiquid template:
Hello {{Name}} {{Surname}}. Number of Addresses: {{Addresses.size}} - {{Addresses[0].City}} - {{Addresses[1].City}}
With stuff1 object I got the exptected result:
Hello John Smith. Number of Addresses: 2 - New York - Milano
With stuff1Deserialized object I got this result:
Hello John Smith. Number of Addresses: 2 - -
Update as per comment
I find one way to do this:
1 - object dynamic sample:
dynamic dynamicStuff = new
{
Name = "John",
Surname = "Smith",
Obj = new { City = "New York", State = "NY" },// i add this to test object
Addresses = new[]
{
new { City = "New York", State = "NY"},
new { City = "Milano", State = "IT" }
}
};
2 - serializing and deserializing to build dynamic object:
dynamic dynamicStuffDeSerialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(dynamicStuff));
3 - Converting dynamic object to JObject and building Dictionary Of (string, object) by converting JObject to Dictionary:
Dictionary<string, object> keyValuePairs = ConvertJObject(JObject.FromObject(dynamicStuffDeSerialized));
private static Dictionary<string, object> ConvertJObject(JObject jObject)
{
Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
foreach (var property in jObject)
{
if (property.Value.Type == JTokenType.Array)
keyValuePairs.Add(property.Key, ConvertJArray(property.Value.Select(o=>(JObject)o)));
else if (property.Value.Type == JTokenType.Object)
keyValuePairs.Add(property.Key, ConvertJObject((JObject)property.Value));
else
keyValuePairs.Add(property.Key, property.Value.ToString());
}
return keyValuePairs;
}
private static List<Dictionary<string, object>> ConvertJArray(IEnumerable<JObject> jObjects)
{
return jObjects.Select(o => ConvertJObject(o)).ToList();
}
Note That, you can use ToObject to convert JObject To Dictionary, but it's convert just the simple value not object or array, like:
JObject jObject = JObject.FromObject(dynamicStuffDeSerialized);
Dictionary<string, object> dict = jObject.ToObject<Dictionary<string, object>>();
4 - use Hash.FromDictionary not Hash.FromAnonymousObject:
Template templatedynamicStuff = Template.Parse("Hello {{Name}} {{Surname}} City in Object {{Obj.City}}. Number of Addresses: {{Addresses.size}} - {{Addresses[0].City}} - {{Addresses[1].City}}");
string result = templatedynamicStuff.Render(Hash.FromDictionary(keyValuePairs));
Note that, i changed the template by adding City in Object {{Obj.City}}
5 - TEST
Console.WriteLine(result);
6 - OUTCOMES:
Hello John Smith City in Object New York. Number of Addresses: 2 - New York - Milano
Old answers
According to newtonsoft documentation, You can use DeserializeAnonymousType instead of DeserializeObject for deserializing Anonymous Object. but DeserializeAnonymousType needs a definition of Anonymous Type To get the same object.
Like the following code :
var stuff1 = new
{
Name = "John",
Surname = "Smith"
};
var stuff1Serialized = JsonConvert.SerializeObject(stuff1);
var definition = new { Name = "", Surname = "" };
dynamic stuff1Deserialized = JsonConvert.DeserializeAnonymousType(stuff1Serialized, definition);
Update as per comment
You can use JObject or ExpandoObject to get properties names and values, like the following code:
dynamic stuff1 = new
{
Name = "John",
Surname = "Smith"
};
var stuff1Serialized = JsonConvert.SerializeObject(stuff1);
dynamic stuff1DeSerialized1 = JsonConvert.DeserializeObject(stuff1Serialized);
foreach (JProperty property in JObject.FromObject(stuff1DeSerialized1))
{
Console.WriteLine($"Key:{property.Name}, Value:{property.Value}");
}
ExpandoObject stuff1DeSerialized2 = JsonConvert.DeserializeObject<ExpandoObject>(stuff1Serialized, new ExpandoObjectConverter());
foreach(KeyValuePair<string, object> keyValue in stuff1DeSerialized2.ToList())
{
Console.WriteLine($"Key:{keyValue.Key}, Value:{keyValue.Value}");
}
I hope to find other solution and share it with you.

Nested JSON in .NET

Trying to get address and its value to be curly brackets. means json object within a json object.
var jsonObject = new JObject();
dynamic j_obj = new JObject();
j_obj.jsonrpc = "1.0";
j_obj.id = "abc";
j_obj.method = "getrawtransaction";
j_obj.#params = new JArray() as dynamic;
dynamic info = new JObject();
info.txid = "myid";
info.vout = "0";
j_obj.#params.Add(info);
var address = "myaddress";
j_obj.Add(new JProperty(address, "0.01"));
Console.WriteLine(j_obj.ToString());
What I want is "address" and its value to be json object.
This is the output I am getting now.
Output Image
You are adding a value property here
var address = "myaddress";
j_obj.Add(new JProperty(address, "0.01"));
Instead create an object for the address then use that in the property:
dynamic addressItem = new JObject();
addressItem.line1 = "foo";
var address = "myaddress";
j_obj.Add(new JProperty(address, addressItem));
Alternatively, as you have gone down the dynamics route you could do this
j_obj.myaddress = new
{
line1 = "foo"
}
Either of these would create JSON that looks like this:
{
...
"myaddress": { "line1": "foo" }
...
}

Include Dictionary in anonymous type and then serialize to form json

In the following code, I have a dictionary "nissi_params_fields" which I have populated with parameters:
Dictionary<string, string> nissi_params_fields = new Dictionary<string, string>();
string[] separator = { "," };
string[] dfields = form_fields.Split(separator, StringSplitOptions.RemoveEmptyEntries);
string[] ffields = db_fields.Split(separator, StringSplitOptions.RemoveEmptyEntries);
foreach (var field in ffields)
{
NissiMain nm = new NissiMain();
object field_object = nm.nissi_get_object_by_name(field);
string fieldvalue = nm.nissi_get_object_value_by_name(field_object);
nissi_params_fields[field] = fieldvalue;
this.nissiSetStorageItem(save_page, field, fieldvalue);
}
nissi_params_fields["company_id"] = this.nissiGetStorageItem("nissi_base", "ni_companyID");
string nissi_params_id = "";
if (save_type == "edit")
{
nissi_params_fields["id"] = this.nissiGetStorageItem(save_page, "id");
nissi_params_id = this.nissiGetStorageItem(save_page, "id");
}
I now want to create an anonymous type that contains the above "nissi_params_fields" dictionary as a single field "fields", so I first try to convert "nissi_params_fields" to an object "nissi_params_fields_object" that I can use in the Newtonsoft JObject "nissi_params_object":
object nissi_params_fields_object = nissi_params_fields.ToArray();
The challenge is how to convert the dictionary to an object ...how do I do this?
I now want to include the converted object "nissi_params_fields_object" in an anonymous type and then serialize the entire thing to JSON using the Newtonsoft JObject:
JObject nissi_params_object = JObject.FromObject(new
{
apikey = this.nissiGetStorageItem("nissi_base", "ni_apiKey"),
company_id = this.nissiGetStorageItem("nissi_base", "ni_companyID"),
id = nissi_params_id,
fields = nissi_params_fields_object,
});
If you just want to JSON serialize the object you can do:
string jsonString = JsonConvert.SerializeObject(nissi_params_object);
and then append jsonString to the URL.

Convert object of any type to JObject with Json.NET

I often need to extend my Domain model with additional info before returning it to the client with WebAPI. To avoid creation of ViewModel I thought I could return JObject with additional properties. I could not however find direct way to convert object of any type to JObject with single call to Newtonsoft JSON library. I came up with something like this:
first SerializeObject
then Parse
and extend JObject
Eg.:
var cycles = cycleSource.AllCycles();
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var vm = new JArray();
foreach (var cycle in cycles)
{
var cycleJson = JObject.Parse(JsonConvert.SerializeObject(cycle, settings));
// extend cycleJson ......
vm.Add(cycleJson);
}
return vm;
I this correct way ?
JObject implements IDictionary, so you can use it that way. For ex,
var cycleJson = JObject.Parse(#"{""name"":""john""}");
//add surname
cycleJson["surname"] = "doe";
//add a complex object
cycleJson["complexObj"] = JObject.FromObject(new { id = 1, name = "test" });
So the final json will be
{
"name": "john",
"surname": "doe",
"complexObj": {
"id": 1,
"name": "test"
}
}
You can also use dynamic keyword
dynamic cycleJson = JObject.Parse(#"{""name"":""john""}");
cycleJson.surname = "doe";
cycleJson.complexObj = JObject.FromObject(new { id = 1, name = "test" });
If you have an object and wish to become JObject you can use:
JObject o = (JObject)JToken.FromObject(miObjetoEspecial);
like this :
Pocion pocionDeVida = new Pocion{
tipo = "vida",
duracion = 32,
};
JObject o = (JObject)JToken.FromObject(pocionDeVida);
Console.WriteLine(o.ToString());
// {"tipo": "vida", "duracion": 32,}
This will work:
var cycles = cycleSource.AllCycles();
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var vm = new JArray();
foreach (var cycle in cycles)
{
var cycleJson = JObject.FromObject(cycle);
// extend cycleJson ......
vm.Add(cycleJson);
}
return vm;
JObject.FromObject(obj);
Documentation here

Categories