So I'm trying to serialize a Dictionary:
Dictionary<string, List<MyClass>>
My class contains a property called MyPropery
However the string comes out as "{"List1":[{"MyProperty":[]}]}"
How would I be able to make it convert to {"List1":["MyClass":{"MyProperty":[]}]}
To achieve what you want, you would need something like:
var obj = new Dictionary<string, List<Dictionary<string, MyClass>>>();
As kalimag pointed out, ["attr": "value"] isn't a valid JSON. The serialization of the object obj, illustrated above, could yield something like:
{"List1": [{"MyClass": {"MyProperty": []}}]}
Which is a valid JSON.
Related
I'm having some trouble using the JsonConvert.SerializeObject method concerning escape chars in WCF. My web method returns a Stream as follows:
return new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(myObject)));
This works fine apart from one of the properties of myObject is a Dictionary of <string, object>. All of the simple types serialize correctly, however when I try and add my custom class as a value I get the type returned instead of the data. On realising this comes from the serialiser calling .ToString on my custom class I've tried overriding it with:
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
However the returned data now includes escape chars
{
"my_dictionary": {
"elem_1": "{\"Prop1\":null,\"Prop2\":3}",
"elem_2": "{\"Prop1\":null,\"Prop2\":3}",
"int_property" : 123
}
}
Any ideas on how I could avoid my custom class being escaped in this way and returned as an array?
Thanks in advance, Matt
I use JavaScriptSerializer (just replace "Object" with your custom class)
using System.Web.Script.Serialization;
List<Object> list = new List<Object>();
JavaScriptSerializer jss = new JavaScriptSerializer();
string res = jss.Serialize(list);
and get this format with "res" value:
[{"IdEmpresa":1,"Nombre":"Test","URL":"http:/localhost:8080/","Activo":true},IdEmpresa":2,"Nombre":"Test2,","URL":"http://localhost:8081/","Activo":true}]
I've realised there was a mistake in the code. The class that was being serialised actually returned a Dictionary the conversion of the object to a string was causing the behaviour I'd observed and in reality the serializer was perfectly able to serialise the objects correctly.
I'm deserializing (or parsing) a json string to a c# object (using Json.NET) and getting a JObject. I want to iterate all the properties with the key "bla", in the same way iterating all xml elements that named "bla" with XElement.Elements("bla").
If it's not possible, I would like to deserialize my json string into a c# object, and work dynamically and recursively on my deserialized json object (my json string can have lists / arrays that can have objects of 2 types.
In the end after editing my object (changing values and removing or adding properties) I need to serialize my object back to a json string.
Which is the best and easiest way to use json serializing and deserializing?
my Json looks like this:
{"Families":{"Family":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}, {"propA":"dhsj", "propB":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}, {"propA":"dhsj", "propB":"fghfgh"}]}]}
in conclusion, the json value is a json object that it's value is a list/array, the list/array can contain 2 "types" of objects, and one of these types also has a property which it's value is a json object that it's value is a list/array, and it goes like this recursively. sometimes the value of one of the props of the type that doesn't have a property which it's value is a json object that it's value is a list/array, can be a list/array itself, that can contain only 1 type of the two mentioned.
If you don't need a strongly-typed object, you can deserialize to a dictionary:
Dictionary<string, object> myObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
And then just use it as a dictionary:
myObject["Property"] = value;
Or
foreach(var propertyKey in myObject.Keys)
{
// do something with each property
Console.WriteLine($"{propertyKey} = {myObject[propertyKey]}");
}
Here's a fiddle
You can serialize it back after you are done
My json looks more like this:
{"Familys":{"Family":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}]}
For JSON like this:
var json = #"{
""Families"":{
""Family"":[
{
""propA"":""Top""
},
{
""propA"":""Top.Lower"",
""Families"":{
""Family"":[
{
""propB"":""propB value""
},
{
""propA"":""Top.Lower.EvenLower"",
""Families"":{
""Family"":[
{
""propA"":""Top.Lower.EvenLower.EvenLower""
}
]
}
}
]
}
}
]
}
}";
Do something like this:
//calling code makes use of "dynamic" to make things clean and readable.
dynamic parsedJson = JsonConvert.DeserializeObject(json);
var allPropAValues = GetPropAValues(parsedJson);
//**** NOTE: this has our extra property ****
var jsonWithExtraStuffProperty = JsonConvert.SerializeObject(parsedJson);
//recursive function that reads AND writes properties
public static List<string> GetPropAValues(dynamic obj)
{
var propAValues = new List<string>();
//**** NOTE: the use of an added property ****
obj.ExtraStuff = new Random().Next();
//if we have a propA value, get it.
if (obj.propA != null)
propAValues.Add(obj.propA.Value);
//iterate through families if there are any. your JSON had Families.Family.
if (obj.Families != null)
foreach (dynamic family in obj.Families.Family)
propAValues.AddRange(GetPropAValues(family));
return propAValues;
}
I'm trying to create a dynamic object from a JSON string in C#. But i can't get it done.
Normally i would get a JSON string through a web service call but in this case I simply created a simple class which I turn into a JSON string. Then I try to turn it back into a dynamic object with the exact same structure as if it was an instance of the Entity class. But that's where I'm having trouble.
This is the class that i turn into a JSON string:
public class Entity
{
public String Name = "Wut";
public String[] Scores = {"aaa", "bbb", "ccc"};
}
Then in somewhere in my code i do this:
var ent = new Entity();
// The Serialize returns this:
// "{\"Name\":\"Wut\",\"Scores\":[\"aaa\",\"bbb\",\"ccc\"]}"
var json = new JavaScriptSerializer().Serialize(ent);
dynamic dynamicObject1 = new JavaScriptSerializer().DeserializeObject(json);
dynamic dynamicObject2 = Json.Decode(json);
When I debug this code then i see that the first dynamicObject1 returns a Dictionary. Not really what I'm after.
The second dynamicObject2 looks more like the Entity object. It has a property called Name with a value. It also has a dynamic array called Scores, but for some reason that list turns out to be empty...
Screenshot of empty Scores property in dynamic object:
So I'm not having any luck so far trying to cast a JSON string to a dynamic object. Anyone any idea how I could get this done?
Using Json.Net
dynamic dynamicObject1 = JsonConvert.DeserializeObject(json);
Console.WriteLine(dynamicObject1.Name);
Using Json.Net but deserializing into a ExpandableOBject, a type that is native to C#:
dynamic obj= JsonConvert.DeserializeObject<ExpandoObject>(yourjson);
If the target type is not specified then it will be convert to JObject type instead. Json object has json types attached to every node that can cause problems when converting the object into other dynamic type like mongo bson.
I'm using C# and Json.NET. If I have a JObject, I want a list of the keys within the object, similar to how object.Keys() returns the keys within the object. This seems like it'd be obvious, but I'm having a rough time finding a way to do this.
Edit:
I'm traversing through the object, and I want to spit out all the keys in the object as I go through. I realize that this example will result in seeing the same key multiple times, and that's OK for my needs.
public void SomeMethod(JObject parent) {
foreach (JObject child in parent.Children()) {
if (child.HasValues) {
//
// Code to get the keys here
//
SomeMethod(child);
}
}
}
IList<string> keys = parent.Properties().Select(p => p.Name).ToList();
Documentation: JObject.Properties
From Converting a JSON.NET JObject's Properties/Tokens into Dictionary Keys
You can simply convert the JObject into a Dictionary object and access the method Keys() from the Dictionary object.
Like this:
using Newtonsoft.Json.Linq;
//jsonString is your JSON-formatted string
JObject jsonObj = JObject.Parse(jsonString);
Dictionary<string, string> dictObj = jsonObj.ToObject<Dictionary<string, string>>();
You can now access those keys via the dictObj.Keys() method. You can see if a key exists by performing dictObj.ContainsKey(keyName) also.
Obviously, you can format the Dictionary however you want (could be Dictionary<string, object>, etc.).
Is it possible to convert a a IEnumerable<KeyValuePair<string,string>> of KeyValuePair to an anonymous type?
Dictionary<string, string> dict= new Dictionary<string, string>();
dict.add("first", "hello");
dict.add("second", "world");
var anonType = new{dict.Keys[0] = dict[0], dict.Keys[1] = dict[1]};
Console.WriteLine(anonType.first);
Console.WriteLine(anonType.second);
********************output*****************
hello
world
The reason i would like to do this is because I am retrieving an object from a webservice that represents an object that does not exist in the wsdl. The returned object only contains a KeyValuePair collection that contains the custom fields and their values. These custom fields can be named anything, so i cant really map an xml deserialization method to the final object i will be using (whose properties must be bound to a grid).
*Just because I used Dictionary<string,string> does not mean it is absolutely a dictionary, i just used it for illustration. Really its an IEnumerable<KeyValuePair<string,string>>
Ive been trying to thing of a way to do this, but am drawing a blank. This is c# .NET 4.0.
You could use the ExpandoObject, it is based on a dictionary.
I think there are a lot of ways to achieve this, but actually converting it in the same Dictionary seems a bit odd to do.
One way to accomplish this, by not actually converting everyting is the following:
public class MyDictionary<T,K> : Dictionary<string,string> // T and K is your own type
{
public override bool TryGetValue(T key, out K value)
{
string theValue = null;
// magic conversion of T to a string here
base.TryGetValue(theConvertedOfjectOfTypeT, out theValue);
// Do some magic conversion here to make it a K, instead of a string here
return theConvertedObjectOfTypeK;
}
}
ExpandoObject is the best option, which I believe is a wrapper around some XML. You could also use an XElement:
var result = new XElement("root");
result.Add(new XElement("first", "hello"));
result.Add(new XElement("second", "world"));
Console.WriteLine(result.Element("first").Value);
Console.WriteLine(result.Element("second").Value);
foreach (var element in result.Elements())
Console.WriteLine(element.Name + ": " + element.Value);
I haven't used ExpandoObject, so I'd try that first because I understand it does exactly what you want and is also something new and interesting to learn.