I'm writting a piece of should which has to parse a JSON object to multiple dictionaries.
I'm familare with parsing the JSON to a simple model object with a JSON helper.
public static class JsonHelper
{
public static string ToJson<T>(T instance)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using (var tempStream = new MemoryStream())
{
serializer.WriteObject(tempStream, instance);
return Encoding.UTF8.GetString(tempStream.ToArray(), 0, Convert.ToInt32(tempStream.Length));
}
}
public static T FromJson<T>(string json)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using (var tempStream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
return (T)serializer.ReadObject(tempStream);
}
}
}
But I need to parse it to multiple dictionary and not model object (which is going to be at the end but for the moment I just need dictionaries).
Regards.
You could use JavaScriptSerializer class (assembly: System.Web.Extensions).
It automatically deserializes JSon strings to object[] (in case of unnamed arrays) or Dictionary<string,object> (in case of named arrays).
e.g.
1)
// txt = [ {A: "foo", B: "bar", C: "foobar"}, {X: "foo", Y: "bar", Z: "foobar"} ]
JavaScriptSerializer ser = new JavaScriptSerializer();
var data = ser.Deserialize<object>(txt);
data will be an object[2], where each sub-object will be a Dictionary<string,object>
2)
// txt = {A: "foo", B: ["bar", 3.4], C: [1, 2, 3]}
JavaScriptSerializer ser = new JavaScriptSerializer();
var data = ser.Deserialize<object>(txt);
data will be a Dictionary<string,object>, where elements at keys "B" and "C" will be objects arrays (object[])
Related
Currently i am using unity to post comments that get saved in a firebase RTDB.
here is the posting code:
Comment NewComment = new Comment("User1", "Great App!");
Dictionary<string, System.Object> childUpdates = new
Dictionary<string, System.Object>();
childUpdates["NewUpdate2"] = NewComment.ToDict();
_database.GetReference("DumbData").UpdateChildrenAsync(childUpdates);
which works well and posts the data to Firebase
For reference here is the Comment Class.
[System.Serializable]
public class Comment
{
public Comment(string Name,string Content)
{
this.Name = Name;
this.Content = Content;
}
public Dictionary<string,System.Object> ToDict()
{
Dictionary<string, System.Object> result = new Dictionary<string, System.Object>();
result["Name"] = this.Name;
result["Content"] = this.Content;
return result;
}
public string Name;
public string Content;
}
and the firebase registers the data received correctly.
but then when receiving the data, i would do
var dataSnapShot = await _database.GetReference("DumbData").GetValueAsync();
var Results = dataSnapShot.GetRawJsonValue();
var temp= JsonUtility.FromJson<Dictionary<string, Comment>>(Results)
but the thing is the FromJSON function returns Nulls everywhere , although the JSON is received correctly matching the structure on Firebase, for reference, the Results variable above looks like this:
{"NewUpdate":{"Content":"Great App!","Name":"User1"},"NewUpdate2":{"Content":"Great App!","Name":"User2"}}
so that's where i am stuck, i cannot deseriazlize the response back to be able to use it.
JsonUtility is very limited with nested objects, dictionaries, etc.
I'll recommend you to use another library for handling JSON serialize and deserialize, you can use Newtonsoft library for example, or use my own JsonManager (the repo includes and example of how it works and how to use it).
Newtonsoft:
Serialize:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
string json = JsonConvert.SerializeObject(product);
// {
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Sizes": [
// "Small"
// ]
// }
Deserialize:
string json = #"{
'Name': 'Bad Boys',
'ReleaseDate': '1995-4-7T00:00:00',
'Genres': [
'Action',
'Comedy'
]
}";
Movie m = JsonConvert.DeserializeObject<Movie>(json);
string name = m.Name;
// Bad Boys
So in your particular case that deserialize is not working, you should do something like:
Dictionary<string, Comment> temp = JsonConvert.DeserializeObject<Dictionary<string, Comment>>(json);
I have the following JSON which I need to manipulate into a different JSON format to be consumed by another process. My data is variable to some extent. Here is an example:
{
"subform_12": {
"multiline_2": "Subform 1 Long Text",
"listpicker_5": "High",
"alpha_1": "SubForm 1 Text"
},
"subform_13": {
"multiline_2": "Subform 2 Long Text",
"alpha_1": "SubForm 2 Text"
}
}
The variable part is the name of the json object (eg "subform_13") and the number and content of name pairs per object (eg "multiline_2": "Subform 1 Long Text").
What I need to do is convert each node into its own chunk of json, as in the following format:
{
"subform_13": [
[{
"fieldKey": "multiline_2",
"value": "Subform 2 Long Text"
},
{
"fieldKey": "alpha_1",
"value": "SubForm 2 Text"
}
]
]
}
Then separately:
{
"subform_13": [
[{
"fieldKey": "multiline_2",
"value": "Subform 2 Long Text"
},
{
"fieldKey": "alpha_1",
"value": "SubForm 2 Text"
}
]
]
}
So far I see that I can iterate thru the list as follows:
var json = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(
jsonString,
new Newtonsoft.Json.JsonSerializerSettings()
{
DateParseHandling = Newtonsoft.Json.DateParseHandling.None,
});
foreach (var item in json)
{
// I can see the "subform_13" and contents here in item , how do I generically extract them?
}
Any help appreciated.
Here is your Main method augmented with the ability to iterate through all values:
static void Main(string[] args)
{
var json = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string,JObject>>(
jsonString,
new Newtonsoft.Json.JsonSerializerSettings()
{
DateParseHandling = Newtonsoft.Json.DateParseHandling.None,
});
foreach (var item in json)
{
var key = item.Key; // "subform_12"
var val = item.Value;
Console.WriteLine(key+":");
foreach (var field in val)
{
var fieldKey = field.Key; // e.g. "multiline_2"
var fieldVal = field.Value; // e.g. "Subform 1 Long Text"
Console.WriteLine($"{fieldKey}={fieldVal.Value<string>()}");
}
Console.WriteLine();
}
}
I am just printing the values out; you would construct your new objects - for example as dynamic - using these values.
The output of my Main is:
subform_12:
multiline_2=Subform 1 Long Text
listpicker_5=High
alpha_1=SubForm 1 Text
subform_13:
multiline_2=Subform 2 Long Text
alpha_1=SubForm 2 Text
Hope it helps.
There are probably more elegant ways using linq, but here's code using a plain old JavaScriptSerializer from System.Web.Extensions.
There is a result dictionary, which you probably don't need if you want each object separated.
The json strings for each object is stored in the allJson list.
Similary, if you want the dictionary objects themselves you could just add seperated to a list during each iteration.
string s = "{\"subform_12\":{\"multiline_2\":\"Subform 1 Long Text\",\"listpicker_5\":\"High\",\"alpha_1\":\"SubForm 1 Text\"},\"subform_13\":{\"multiline_2\":\"Subform 2 Long Text\",\"alpha_1\":\"SubForm 2 Text\"}}";
JavaScriptSerializer ser = new JavaScriptSerializer();
Dictionary<string, object> obj = ser.DeserializeObject(s) as Dictionary<string, object>;
// combined dictionary of all results
Dictionary<string, object> result = new Dictionary<string, object>();
// an intermediary dictionary to house the results of each object
Dictionary<string, object> separated = new Dictionary<string, object>();
// a list to hold the json representation of each separate object
List<String> allJson = new List<string>();
foreach (KeyValuePair<string, object> src in obj)
{
Dictionary<string, object> children = (Dictionary<string, object>)src.Value;
Dictionary<string, object> t = new Dictionary<string, object>();
separated = new Dictionary<string, object>();
List<object> l = new List<object>();
foreach (KeyValuePair<string, object> child in children)
{
t.Add("fieldKey", child.Key);
t.Add("value", child.Value);
l.Add(t);
t = new Dictionary<string, object>();
}
separated.Add(src.Key, l.ToArray());
allJson.Add(ser.Serialize(separated));
result.Add(src.Key, l.ToArray());
}
// final string containing all transformed objects combined.
string combined = ser.Serialize(result);
I am trying to parse a json and populate these values into an object with DataContractJsonSerializer. Having no luck with this yet.
The json is -
{
"0": [
547,
541,
507,
548,
519,
0
],
"1": [
573,
504
]
}
I have tried the following code:
try
{
string json = #"""0"":[547,541,507,548,519,0],""1"":[573,504]";
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var seraializer = new DataContractSerializer(typeof(MyClass));
var jsonParsed = seraializer.ReadObject(memStream);
}
}
catch(Exception ex)
{
}
Always getting an exception that the data is invalid at the root. But online json validators say this is a valid json.
MyClass -
[DataContract]
public class MyClass
{
[DataMember]
public Dictionary<string, List<int>> values { get; set; }
}
Thanks Patrick for providing me a working solution with Newtonsoft. But just to learn , I want to see what am I doing wrong with DataContractJsonSerializer. The code below gives me no exception, but I am not getting any values after the parsing is complete.
string json = #"{""0"":[547,541,507,548,519,0],""1"":[573,504]}";
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var seraializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<int>>));
var jsonParsed = seraializer.ReadObject(memStream);
}
You should use Dictionary<string, List<int>> as the type to deserialize to. You also need to use the right serializer (DataContractSerializer is for XML, DataContractJsonSerializer for JSON):
var seraializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<int>>), new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = true });
var jsonParsed = seraializer.ReadObject(memStream);
Or for JSON.NET:
var x = JsonConvert.DeserializeObject<Dictionary<string, List<int>>>(json);
This question already has answers here:
Deserialize JSON into C# dynamic object?
(31 answers)
Closed 8 years ago.
I have JSON which I need to deserialize, but I don't want to create class with property name.
here's what I get in JSON:
"[{"id":1,"width":100,"sortable":true}, {"id":"Change","width":100,"sortable":true}]"
So how could I do this?
Thanks for advance:)
You can use JavaScriptSerializer
var list = new JavaScriptSerializer()
.Deserialize<List<Dictionary<string, object>>>(json);
var id = list[0]["id"];
Or if you want, Json.Net
var list2 = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(json);
Json.Net also allows you to use dynamic
dynamic list = JsonConvert.DeserializeObject(json);
var wdth = list[0].width;
Using Json.net, you can deserialize directly to an anonymous class:
var json = "[{\"id\":1,\"width\":100,\"sortable\":true}, \"id\":\"Change\",\"width\":100,\"sortable\":true}]";
var myExempleObject = new {id = new object(), width = 0, sortable = false};
var myArray = JsonConvert.DeserializeAnonymousType(json, new[] {myExempleObject});
I'm assuming here id can be any object (as in your exemple it can be an int or a string), width must be an int and sortable must be a boolean.
You may use json.net
I am not sure if it is what you are looking for.
string json = #"{
'CPU': 'Intel',
'PSU': '500W',
'Drives': [
'DVD read/writer'
/*(broken)*/,
'500 gigabyte hard drive',
'200 gigabype hard drive'
]
}";
JsonTextReader reader = new JsonTextReader(new StringReader(json));
while (reader.Read())
{
if (reader.Value != null)
Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value);
else
Console.WriteLine("Token: {0}", reader.TokenType);
}
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
class Program
{
static void Main(string[] args)
{
string json = "[{\"id\":1,\"width\":100,\"sortable\":true}, {\"id\":\"Change\",\"width\":100,\"sortable\":true}]";
JArray array = JsonConvert.DeserializeObject(json) as JArray;
if (array != null)
{
foreach (JObject jObj in array)
Console.WriteLine("{0,10} | {1,10} | {2,10}", jObj["id"], jObj["width"], jObj["sortable"]);
}
Console.ReadKey(true);
}
}
I need to create a Json object dynamically by looping through columns.
so declaring an empty json object then add elements to it dynamically.
eg:
List<String> columns = new List<String>{"FirstName","LastName"};
var jsonObj = new {};
for(Int32 i=0;i<columns.Count();i++)
jsonObj[col[i]]="Json" + i;
And the final json object should be like this:
jsonObj={FirstName="Json0", LastName="Json1"};
[TestFixture]
public class DynamicJson
{
[Test]
public void Test()
{
dynamic flexible = new ExpandoObject();
flexible.Int = 3;
flexible.String = "hi";
var dictionary = (IDictionary<string, object>)flexible;
dictionary.Add("Bool", false);
var serialized = JsonConvert.SerializeObject(dictionary); // {"Int":3,"String":"hi","Bool":false}
}
}
I found a solution very similar to DPeden, though there is no need to use the IDictionary, you can pass directly from an ExpandoObject to a JSON convert:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
foo.Test = true;
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
and the output becomes:
{ "FirstName":"John", "LastName":"Doe", "Active":true }
You should use the JavaScriptSerializer. That can Serialize actual types for you into JSON :)
Reference: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
EDIT: Something like this?
var columns = new Dictionary<string, string>
{
{ "FirstName", "Mathew"},
{ "Surname", "Thompson"},
{ "Gender", "Male"},
{ "SerializeMe", "GoOnThen"}
};
var jsSerializer = new JavaScriptSerializer();
var serialized = jsSerializer.Serialize(columns);
Output:
{"FirstName":"Mathew","Surname":"Thompson","Gender":"Male","SerializeMe":"GoOnThen"}
Using dynamic and JObject
dynamic product = new JObject();
product.ProductName = "Elbow Grease";
product.Enabled = true;
product.StockCount = 9000;
Console.WriteLine(product.ToString());
// {
// "ProductName": "Elbow Grease",
// "Enabled": true,
// "StockCount": 9000
// }
Or how about:
JObject obj = JObject.FromObject(new
{
ProductName = "Elbow Grease",
Enabled = true,
StockCount = 9000
});
Console.WriteLine(obj.ToString());
// {
// "ProductName": "Elbow Grease",
// "Enabled": true,
// "StockCount": 9000
// }
https://www.newtonsoft.com/json/help/html/CreateJsonDynamic.htm