I ma using Newtonsofts' Json.Net to serialize some and array of objects to json.
The objects have a common set of properties but also have Meta property which is a dictionary
During serialization I want the key value pairs to be added to my json object as if they where root level properties, like this...
{
id: 1,
name:'jeff',
food:'spinch',
spoon: 'ýes'
}
Not like this:
{
id: 1,
name:'jeff',
meta:{
food:'spinch',
spoon: 'ýes'
}
}
I have dug through JsonSerializerSettings but cant seem to spot where I can jump in and override???
You can do this by creating your own JsonConverter and then adding an attribute to the class you want to serialize
[JsonConverter(typeof(MyConverter))]
Example here -
http://www.lostechies.com/blogs/rhouston/archive/2008/02/25/a-custom-converter-for-json-net.aspx
If your dictionary is a string to object dictionary could can simply use the [JsonExtensionData] attribute:
[JsonExtensionData]
public Dictionary<string, object> Meta { get; set; }
See How to serialize a Dictionary as part of its parent object using Json.Net.
You could use the .Net DataContractJsonSerializer.
For custom serialization, see:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.idatacontractsurrogate.aspx
One advantage of using IDataContractSurrogate (compared to simply adding properties to your class for serialization) is that you don't have to mix actual properties and serialization properties together in the same class.
Another advantage (compared to having to do custom serialization against a property bag, ala KeyValuePairConverter) is that you only have to add attributes to properties on your classes (the actual type and the surrogate type) and you can write all your conversion/custom serialization code directly against those types. This keeps your code higher level, and lets the framework deal with the exact transport mechanism.
Related
I came across this (seemingly usual) scenario but I could not find a satisfying solution. Maybe someone knows:
For some reason I parse JSON and I allow the user to provide more key-value pairs than my class has properties. I store the arbitrary ones away like so:
class MusterNode
{
// some definite property
public string TypeName { get; set; }
// takes the rest
// see https://www.newtonsoft.com/json/help/html/DeserializeExtensionData.htm
[JsonExtensionData]
private Dictionary<string, JToken> _extparams;
}
If I deserialize something like
{
"TypeName": "a",
"stuff": 3
}
TypeName will be set and my _extparams contains a key "stuff".
For some reason I want to apply that stored data to another (just created) object 'obj' (in fact the parameters were thought for that typename thingy).
So I have a Dictionary and an object. Is there a way to 'apply' the dictionary without serializing it first?
My non-satisfying solution is this:
string json = JsonConvert.SerializeObject(_extparams);
JsonConvert.PopulateObject(json, obj);
decorated with some JsonSerializerSettings, this works for me. But it does unnecessary work.
Json.Net does not have a method which will populate an object directly from a standard dictionary. After all, it is a serialization library, not a mapping library. That said, there is a way to make it work without the intermediate serialization/deserialization step.
First, instead of using a Dictionary<string, JToken> as the container for your [JsonExtensionData] parameters, use a JObject. JObject implements IDictionary<string, JToken>, so it will still work to catch the extra properties.
class MusterNode
{
...
[JsonExtensionData]
private JObject _extparams;
}
Then, to populate the other object, you just need to create a reader from the JObject and pass it to JsonSerializer.Populate() like this:
new JsonSerializer().Populate(_extparams.CreateReader(), obj);
If you have specific serialization settings you need, you can set them directly on the JsonSerializer prior to calling Populate().
Here is a working demo: https://dotnetfiddle.net/kIzc5G
I used the $type properties in Json for the deserialization of inherited objects (to choose the correct object type in which to deserialize at runtime)
I do this using :
config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings{ TypeNameHandling = TypeNameHandling.Objects}
this line is in the WebApiConfig file.
It works fine but I can't figure out how to restrict the $type only to the webservices who actually needs it (I only need it for one PUT and one POST).
The $type is messing up the API results for the other webservices and I can't find some TypeNameHandling configuration nor some serialization option to avoid this.
Does anyone knows how to do that?
Cheers!
To enable type name handling on a nested object, you can attach [JsonProperty(ItemTypeNameHandling = TypeNameHandling.Objects)] to the containing property, like so:
public class RootObject
{
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Objects)]
public object Data { get; set; }
}
There's no builtin way to enable type name handling on a specific type, and so there's no builtin way to enable type name handling on the root object. Instead, you could use the EnableJsonTypeNameHandlingConverter from SignalR Typenamehandling if you need to do this.
Thanks for the help dbc. I had other issues during deserialization (using a OData.Delta object and the solution you proposed didn't actually fit completely the need.
I overcame the issue thanks to this post : Custom Json.NET serializer settings per type
to have the $type customization only for a few webservices.
I am using Newtonsoft.Json to serialize/deserialize my C# object to/from JSON.
My C# object has a property of following type:
List<BaseClass> objects { get; set; }
This collection holds different child objects (e.g. - ChildClass1, ChildClass2).
Serializing to JSON works fine but while deserializing it creates objects of BaseClass in collection (which is obvious :)).
Is there a way I can create concrete child objects while deserializing?
I tried creating a custom converter by implementing CustomCreationConverter<BaseClass>. But the problem is overridden Create method gives me just the type and based on that I cannot decide which object to return (ChildClass1 or ChildClass2)
My JSON string has a Type property by which I can identify the child object to create.
Any help is highly appreciated.
You can use the TypeNameHandling option:
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }
JsonConvert.SerializeObject(myObject, Formatting.Indented, settings );
The TypeNameHandling option "Auto" ensures that type names are included in the serialized JSON
for subclasses. But watch out: these names become invalid when the classes or their namespaces are renamed!
I am writing a C# wrapper for a RESTful JSON API, and using Json.NET to deserialize the incoming json to strongly typed object. but a few properties in the incoming json are highly dynamic, it will be some json object with different number and type of properties. My current solution is, I mapped the dynamic json property to Dictionary<string, object> (Nested dictionary) in my C# class,and write Custom JsonConverter to convert dynamic json to Nested dictionary. My class look like this:
public class Item
{
[JsonProperty("item_id")]
public int ItemId { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
//Property to map dynamic json object
[JsonProperty("data")]
public Dictionary<string, object> Data { get; set; }
}
It was successful.
The problem is, its very difficult to to access data from this nested dictionary for the end users, we can't even see what is the structure of data without debugging it in Visual studio. Now i am planning to use JObject or JArray instead of nested dictionary. So that we can see the structure of data by just calling ToString method (Will output the original json data as string) as well as this types have LINQ support so that users can access data from it easily.
Is this a good practice use this, considering JObject and JArray types both depend on a third party library (Anyway Json.NET is a dependency for my library because i am using it for json serialization) . Or there some other ways to do this ?
You should use ExpandoObjectConverter instead.
You need to type your IDictionary<string, object> as just dynamic and decorate the whole property with [JsonConverter(typeof(ExpandoObjectConverter))].
One interesting detail is ExpandoObject also implements IDictionary<string, object>, but when you type it with dynamic, you can access associated properties like regular ones! ;)
Using ASP.NET 4.0 C#, how would I be able to change the serialization of a list containing name/value object into a JSON object that is of the format:
{
name:value,
name1:value1,
name2:value2
}
Instead of
{
{name:name, value:value},
{name:name1, value:value1},
{name:name2, value:value2}
}
The name/value object in the dictionary is dynamic in terms of the keys that will exist inside. One workarounds would be to create custom object which will have the explicit properties available - However this approach is not scalable, therefore this question :)
Thanks.
You could implement a custom JavaScriptConverter, then you're in full control of the serialization. Or put all your properties into an IDictionary and JSON that and I think it will come out in the format you're after.