Created
December 20, 2018 09:07
-
-
Save mjul/74a12286c129476c0c5bf175ecf38de1 to your computer and use it in GitHub Desktop.
Using JsonConverter<T> with NewtonSoft Json to serialize a class as an object where the keys and values are defined dynamically in a dictionary member of the class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<TargetFramework>netcoreapp2.1</TargetFramework> | |
<IsPackable>false</IsPackable> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> | |
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> | |
<PackageReference Include="xunit" Version="2.4.0" /> | |
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | |
</ItemGroup> | |
</Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
using Xunit; | |
using Xunit.Abstractions; | |
namespace JsonNetSerialization | |
{ | |
[JsonObject(ItemConverterType = typeof(NotQuiteADictionaryConverter))] | |
public class Parent | |
{ | |
// The converter defined above should serialize this as a JSON object | |
[JsonProperty("child")] public NotQuiteADictionary Child { get; set; } | |
} | |
public class NotQuiteADictionary | |
{ | |
private readonly SortedDictionary<string, string> _contents = new SortedDictionary<string, string>(); | |
public void Add(string key, string value) | |
{ | |
_contents[key] = value; | |
} | |
public IReadOnlyDictionary<string, string> ToDictionary() | |
{ | |
return _contents; | |
} | |
} | |
public class NotQuiteADictionaryConverter : JsonConverter<NotQuiteADictionary> | |
{ | |
public override void WriteJson(JsonWriter writer, NotQuiteADictionary value, JsonSerializer serializer) | |
{ | |
// Serialize the instances to a dictionary where the keys and values are | |
// from the dictionary defined in a field (property) inside the class | |
serializer.Serialize(writer, value.ToDictionary()); | |
} | |
public override NotQuiteADictionary ReadJson(JsonReader reader, Type objectType, | |
NotQuiteADictionary existingValue, | |
bool hasExistingValue, JsonSerializer serializer) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
public class JsonSerializationTest | |
{ | |
private readonly ITestOutputHelper _testOutputHelper; | |
public JsonSerializationTest(ITestOutputHelper testOutputHelper) | |
{ | |
_testOutputHelper = testOutputHelper; | |
} | |
[Fact] | |
public void CanSerializeNotQuiteADictionaryAsJsonObject() | |
{ | |
var child = new NotQuiteADictionary(); | |
child.Add("foo", "fooValue"); | |
child.Add("bar", "barValue"); | |
var parent = new Parent() | |
{ | |
Child = child | |
}; | |
// Expected JSON, note that the path to the dictionary members is directly on the child, not .child.contents | |
// { | |
// "child": { | |
// "bar": "barValue", | |
// "foo": "fooValue" | |
// } | |
// } | |
var json = JsonConvert.SerializeObject(parent, Formatting.Indented); | |
_testOutputHelper.WriteLine(json); | |
var deserialized = JObject.Parse(json); | |
Assert.IsType<JObject>(deserialized["child"]); | |
Assert.Equal("fooValue", deserialized["child"]["foo"].Value<string>()); | |
Assert.Equal("barValue", deserialized["child"]["bar"].Value<string>()); | |
Assert.Equal(2, deserialized["child"].Count()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment