In C#, I have successfully serialized an anonymous object into JSON by use of code like this...
var obj = new { Amount = 108, Message = "Hello" };
JavaScriptSerializer serializer = new JavaScriptSerializer();
String output = serializer.Serialize(obj);
However, what I would like to be able to do later is to deserialize the JSON string back into an anonymous object. Something like this...
var obj2 = serializer.Deserialize(output, object);
But the serializer.Deserialize() method requires a second parameter that is the type of object it will deserialize to.
I tried this...
var obj2 = serializer.Deserialize(output, obj.GetType());
But this produces an error:
No parameterless constructor defined for type of '<>f__AnonymousType0`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.
I'm not sure what this error means.
how about dynamics, the fastest way I see is this:
dynamic myObject = JsonConvert.DeserializeObject<dynamic>(output);
decimal Amount = Convert.ToDecimal(myObject.Amount);
string Message = myObject.Message;
Note:
You will need Newtonsoft.json.dll reference
JSON.Net is a powerful library to work with JSON in .Net
There's a method DeserializeAnonymousType you can tap in to.
Update: Json.Net is now included with ASP.Net, however my latest favorite that I use is JsonFX. It's got great linq support as well, check it out.
Update 2: I've moved on from JsonFX, and currently use ServiceStack.Text, it's fast!
How about using the DeserializeObject method, it does not require a specific type. This also solved a similar SO question. The method deserializes to a Dictionary<string, object> containing name/value pairs.
Update: to clarify the error you get when doing this:
var obj2 = serializer.Deserialize(output, obj.GetType());
Given the type of obj, Deserialize will try to create a new instance of the type using a default constructor. Anonymous types in C# does not have a public parameterless constructor, and thus the operation fails.
This can also be done using the in-built JavaScriptSerializer, as follows:
object result = new JavaScriptSerializer().DeserializeObject(JSONData);
This will return an object[] instance, with Key-Value pairs.
Recently I have been using the awesome JsonFx.Net library and I've come to appreciate what it does. You can use Nuget Package Manager to install it right inside Visual Studio.
The code goes like this,
var reader = new JsonReader();
string input = #"{ ""first"": ""Foo"", ""last"": ""Bar"" }";
var template = new { first=String.Empty, middle=String.Empty, last=String.Empty };
var output = reader.Read(input, template);
As you can see you can even specify the template for Anonymous Type.
if you use Newtonsoft.Json you can try DeserializeAnonymousType method
var obj1 = new { Amount = 108, Message = "Hello" };
var json=JsonConvert.SerializeObject(obj1);
// or as well
var json= "{ \"Amount\" : 108, \"Message\" : \"Hello\" }";
//Deserialization
var definition = new { Amount = 0, Message = "" };
//obj2 type is "anonymous"
var obj2 = JsonConvert.DeserializeAnonymousType(json,definition);
result
{ Amount = 108, Message = "Hello" }
If you do not want to manually provide the type i found the easyest way is just:
var jsonString = JsonHelper.SerializeObject(item);
ExpandoObject obj = JsonHelper.DeserializeObject<ExpandoObject>(jsonString);
You can use JObject instead to deserialize the JSON string:
using Newtonsoft.Json.Linq;
string output = "{\"Amount\" = 108, \"Message\" = \"Hello\"}";
var amount = JObject.Parse(output)["Amount"];
Related
Normally I'm using Newtonsoft to deserialize like this
List<myObject> deserializeObj = JsonConvert.DeserializeObject<List<myObject>>(mysample);
But now, i'm facing a problem where the attribute of mysample can be dynamic which is user define themselves. Thus i cannot use myObject anymore as it is fixed class. So how can i deserialize object like that?
For example the mysample can be something like bellow and etc:
[{"Name":"a","Phone":"a","Ic":"a"},{"Name":"b","Phone":"b","Ic":"b"}]
OR
[{"Id":"a"},{"Id":"b"}]
Target Framework is .NET Framework 3.5
you can use Dynamic Type
List<dynamic> deserializeObj = JsonConvert.DeserializeObject<List<dynamic>>(mysample);
.NET Framework 3.5 :
List<object> deserializeObj = JsonConvert.DeserializeObject<List<object>>(mysample);
well you can then use reflection to access value
sample:
System.Reflection.PropertyInfo pi = item.GetType().GetProperty("name");
String name = (String)(pi.GetValue(item, null));
dotnt forget to add using System.Reflection;
To avoid using dynamic, you can parse the json using JArray
JArray array = JArray.Parse(json);
Thus i cannot use myObject anymore as it is fixed class. So how can i deserialize object like that?
To get rid from this problem Newtonsoft.Json have very well feature that we can use
If you don't know which json object or array comes from your resource. means you can't determine its c# respective object then newtonsoft have JObject and JArray can handle this problem like
1) Suppose your json string is object like
var json = #"{ 'Name':'a','Phone':'a','Ic':'a'}";
Then you can use JObject here
JObject jObject = JsonConvert.DeserializeObject<JObject>(json);
2) Suppose your json string is array like
var json1 = #"[{ 'Name':'a','Phone':'a','Ic':'a'},{ 'Name':'b','Phone':'b','Ic':'b'}]";
Then you can use JArray here
JArray jArray = JsonConvert.DeserializeObject<JArray>(json1);
After successfully getting JArray from your json string. you can also querying on your deserialized object to get particular object from it like
JObject jObject1 = jArray.Children<JObject>().FirstOrDefault();
JObject jObject2 = jArray.Children<JObject>().FirstOrDefault(x => x["Name"] != null && x["Name"].ToString() == "a");
int count = jArray.Children<JObject>().Count();
If you want to get certain key:value pair from your json then you can get it by below code
JProperty jProperty = jObject1.Properties().Where(x => x.Name == "Name").FirstOrDefault();
var value = (string)jProperty.Value;
Try once may it help you.
I need to pass a Json object to an API, but the API requires the Json properties to have a double label of sorts, such as:
{
"name:id":"1234"
}
However, using Newtonsoft.Json.Linq, I can't get this to format the label exactly. Here is what I've tried so far (which throws an error)
dynamic json= new JObject();
json.name.id = "1234";
Doing
json.id = "1234";
Works just fine. I have also tried
json.name = new JProperty("id", "1234");
Which also throws an error. I have also tried hard coding the json file as a single string and converting that to a JObject, which also threw an error. Is what I'm trying to do possible or am I missing something? Is there another Json package I could use that would support what I want to do?
Use JObject's string indexer notation.
dynamic json = new JObject();
json["name.id"] = "1234";
Since the json is essentially built as a key/value pair, using a string indexer can allow you to overcome atypical property names.
There multiple ways to achieve that.
You can use JsonProperty attribute and specify the property name as name:id like:
class MyClass
{
[JsonProperty("name:id")]
public string Name_Id { get; set; }
}
and then you can do:
MyClass obj = new MyClass();
obj.Name_Id = "1234";
var strJson = JsonConvert.SerializeObject(obj);
and you will get back:
{"name:id":"1234"}
I have a JSON object, something like:
var jsonObject = {"att1" : "val1","att2" : "val2","att3" : "val3","att4" : "val4"}
I need to convert the same into an ExpandoObject.
I tried something like:
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<List<ExpandoObject>>(jsonObject,
expConverter);
But it is not giving me the desired result.
Can someone help me get the result?
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(jsonObject, expConverter);
Your JSON object isn't an array, so you can't serialize to a List<>. Just serialize to the object directly instead.
I see two issues, preventing the code to work:
The syntax of your jsonObject declaration is not correct. Declare it as a string and inside the string use the escape "backslash + double quote" for every double quote:var jsonObject = "{\"att1\": \"val1\",\"att2\": \"val2\",\"att3\": \"val3\",\"att4\": \"val4\"}";
Then, when using Newtonsoft.Json.Converters, instead of List<ExpandoObject> it needs to be ExpandoObject in the type argument, because an ExpandoObject is inside already a dictionary (not a list):dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(jsonObject, expConverter);
The following code fixes the two issues mentioned above and displays the key/value pairs on screen:
using System.Dynamic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
void Main()
{
// 1. this needs to be a string
var jsonObject =
"{\"att1\": \"val1\",\"att2\": \"val2\",\"att3\": \"val3\",\"att4\": \"val4\"}";
var expConverter = new ExpandoObjectConverter();
// 2. the correct type argument is ExpandoObject
dynamic obj =
JsonConvert.DeserializeObject<ExpandoObject>(jsonObject, expConverter);
// display the keys and values on screen
foreach (var o in obj)
{
Console.WriteLine($"{o.Key}, {o.Value}");
}
}
The output is:
att1, val1
att2, val2
att3, val3
att4, val4
Note: You can easily convert the expando to a dictionary (internally it already is an IDictionary) like:
var dict = new Dictionary<string, object>(obj);
That allows to do a dict.Dump() in LinqPad (not supported with ExpandoObject)
If you're trying it out in LinqPad press F4 and add the NUGET package Json.NET (if you don't have the paid version of LinqPad, NUGET function is limited there - try Rock.Core.Newtonsoft in this case).
I have a DynamicJsonObject like:
var obj = new DynamicJsonObject();
obj.Field1 = "field1";
obj.Field2 = "field2";
I need the obj's json string. I tried using JavaScriptSerializer:
var json = JavaScriptSerializer.Serialize(obj);
But the result is always json == '{}'
Is there a workaround for this? preferably not using third party libraries
You can add custom converter to JavaScriptSerializer. In System.Web.Helpers one already exists but is internal - you can use the following code to register it:
var type = Type.GetType("System.Web.Helpers.DynamicJavaScriptConverter, System.Web.Helpers");
var converter = (JavaScriptConverter)Activator.CreateInstance(type);
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { converter });
var json = serializer.Serialize(obj);
or copy code from here
Thanks for your answers, but I've found a simple way to do this by using System.Web.Helpers.Json.
So, my code looks like this:
string json = Json.Encode(obj);
I cannot use an anonymous object, because I don't create obj, it is provided in the DynamicJsonObject 'format' already.
I had the cunning idea of using a dynamic variable to test the results of a method that returns an anonymous type - more specifically it returns a JsonResult, which as json looks like this
{ "newData" : [ 1120741.2697475906,
826527.64681837813
],
"oldData" : [ 1849870.2326665826,
1763440.5884212805
],
"timeSteps" : [ 0,
4.8828124999999998e-10
],
"total" : 2
}
I can read the JSonResult which will give me the anonymous type. Here's my code:
var jsonResult = controller.GetChangeData(1) as JsonResult;
dynamic data = jsonResult.Data;
Assert.AreEqual(2, data.total); // This works fine :)
But how do I get at "newData" for example? This code....
var newData = data.newData;
Gives me a System.Linq.Enumerable.WhereSelectArrayIterator, but I don't know what to do with it to be able to just use it as an arry of doubles.
I tried casting it as a double[], but it doesn't work either.
As an aside, can I easily check if a property is defined on the dynamic?
The reason .ToArray() doesn't work is that it's an extension method, and extension methods aren't available at runtime. That just means you have to call the function statically. Does Enumerable.ToArray<double>(data.newData) work?
You may need Enumerable.ToArray(Enumerable.Cast<double>(data.newData)) depending on what elements newData actually has.
To get the properties of an instance of a dynamic type
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(dyn);
foreach (PropertyDescriptor prop in props)
{
object val = prop.GetValue(dyn);
var propName = prop.Name;
var propValue = val;
}
where dyn is an instance of a dynamic object.
Could you use the JavaScriptSerializer class to parse the Json string into a dynamic variable? Eg:
var serializer = new JavaScriptSerializer();
var jsonObj = serializer.Deserialize<dynamic>(jsonString);
var newData1 = jsonObj["newData"][0];