Skip to content

Instantly share code, notes, and snippets.

@kzu
Created May 21, 2014 16:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kzu/abb7d77e34734834d76c to your computer and use it in GitHub Desktop.
Save kzu/abb7d77e34734834d76c to your computer and use it in GitHub Desktop.
Json.NET Extensibility Example
namespace JsonExtensibility
{
public class JsonTests
{
[Fact]
public void when_serializing_itask_then_can_customize_properties ()
{
var serializer = new JsonSerializer {
Formatting = Formatting.Indented,
};
var task = new MyTask {
InputScalar = "Scalar",
InputSingle = new TaskItem ("Foo.cs", new Dictionary<string, string> { { "Key", "Value" } }),
InputMany = new ITaskItem[]
{
new TaskItem ("Many1.cs", new Dictionary<string, string> { { "Key", "Value" } }),
new TaskItem ("Many2.cs", new Dictionary<string, string> { { "Key", "Value" } }),
}
};
serializer.ContractResolver = new TaskContractResolver ();
serializer.Converters.Add (new TaskItemConverter ());
var builder = Serialize (serializer, task);
Console.WriteLine (builder.ToString ());
var deserialized = (MyTask)serializer.Deserialize (new JsonTextReader (new StringReader (builder.ToString ())), typeof (MyTask));
Assert.Equal (task.InputScalar, deserialized.InputScalar);
Assert.Equal (task.InputSingle.ItemSpec, deserialized.InputSingle.ItemSpec);
Assert.Equal (task.InputMany.Count (), deserialized.InputMany.Count ());
var rountrip = Serialize (serializer, deserialized);
Assert.Equal (builder.ToString (), rountrip.ToString ());
}
private static StringBuilder Serialize (JsonSerializer serializer, MyTask task)
{
var builder = new StringBuilder ();
using (var stringWriter = new StringWriter (builder))
using (var jsonWriter = new JsonTextWriter (stringWriter)) {
serializer.Serialize (jsonWriter, task);
}
return builder;
}
public class TaskContractResolver : DefaultContractResolver
{
protected override JsonObjectContract CreateObjectContract (Type objectType)
{
var contract = base.CreateObjectContract (objectType);
if (typeof (Task).IsAssignableFrom (objectType)) {
foreach (var property in contract.Properties.Where (x => x.DeclaringType != objectType).ToArray ()) {
contract.Properties.Remove (property);
}
}
return contract;
}
}
public class TaskItemConverter : JsonConverter
{
public override bool CanConvert (Type objectType)
{
return typeof (ITaskItem).IsAssignableFrom (objectType);
}
public override object ReadJson (JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<SerializableTaskItem> (reader).ToTaskItem ();
}
public override void WriteJson (JsonWriter writer, object value, JsonSerializer serializer)
{
var item = (ITaskItem)value;
serializer.Serialize (writer, new SerializableTaskItem (item));
}
}
public class SerializableTaskItem
{
public SerializableTaskItem ()
{
}
public SerializableTaskItem (ITaskItem item)
{
this.ItemSpec = item.ItemSpec;
this.Metadata = item.CloneCustomMetadata ();
}
public ITaskItem ToTaskItem ()
{
return new TaskItem (this.ItemSpec, this.Metadata);
}
public string ItemSpec { get; set; }
public IDictionary Metadata { get; set; }
}
}
public class MyTask : Task
{
public string InputScalar { get; set; }
public ITaskItem InputSingle { get; set; }
public ITaskItem[] InputMany { get; set; }
public override bool Execute ()
{
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment