Last active
July 19, 2018 03:44
-
-
Save flakey-bit/825b776d8255733835a7b4351529f58e to your computer and use it in GitHub Desktop.
Deserialize recursive subclasses via enum w/ Json.NET (Newtownsoft.JSON)
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 Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
namespace Questionaire | |
{ | |
internal class QuestionaireNodeConverter : JsonConverter | |
{ | |
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |
{ | |
throw new NotImplementedException(); | |
} | |
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |
{ | |
if (reader.TokenType == JsonToken.Null) | |
{ | |
return null; | |
} | |
if (!IsAbstractDecendantOf<QuestionaireNode>(objectType)) | |
{ | |
serializer.ContractResolver.ResolveContract(objectType).Converter = null; | |
return serializer.Deserialize(reader, objectType); | |
} | |
var jObject = JObject.Load(reader); | |
var nodeTypeValue = jObject.Value<string>("type"); | |
var nodeType = nodeTypeValue.ToEnum<QuestionareNodeType>(); | |
Type nodeImplType; | |
switch (nodeType) | |
{ | |
case QuestionareNodeType.RadioGroup: | |
nodeImplType = typeof(RadioGroupNode); | |
break; | |
case QuestionareNodeType.CalculatedField: | |
nodeImplType = typeof(CalculatedFieldNode); | |
break; | |
case QuestionareNodeType.Currency: | |
nodeImplType = typeof(CurrencyNode); | |
break; | |
case QuestionareNodeType.Date: | |
nodeImplType = typeof(DateNode); | |
break; | |
case QuestionareNodeType.FileUpload: | |
nodeImplType = typeof(FileUploadNode); | |
break; | |
case QuestionareNodeType.Heading: | |
nodeImplType = typeof(HeadingNode); | |
break; | |
case QuestionareNodeType.MultipleColumns: | |
nodeImplType = typeof(MultipleColumnsNode); | |
break; | |
case QuestionareNodeType.MultiSelect: | |
nodeImplType = typeof(MultiSelectNode); | |
break; | |
case QuestionareNodeType.Number: | |
nodeImplType = typeof(NumberNode); | |
break; | |
case QuestionareNodeType.Percentage: | |
nodeImplType = typeof(PercentageNode); | |
break; | |
case QuestionareNodeType.Repeater: | |
nodeImplType = typeof(RepeaterNode); | |
break; | |
case QuestionareNodeType.Select: | |
nodeImplType = typeof(SelectNode); | |
break; | |
case QuestionareNodeType.Tab: | |
nodeImplType = typeof(TabNode); | |
break; | |
case QuestionareNodeType.Text: | |
nodeImplType = typeof(TextNode); | |
break; | |
case QuestionareNodeType.TextArea: | |
nodeImplType = typeof(TextAreaNode); | |
break; | |
default: | |
throw new ArgumentOutOfRangeException(); | |
} | |
return serializer.Deserialize(jObject.CreateReader(), nodeImplType); | |
} | |
public override bool CanConvert(Type objectType) | |
{ | |
return IsAbstractDecendantOf<QuestionaireNode>(objectType); | |
} | |
public override bool CanWrite => false; | |
private bool IsAbstractDecendantOf<T>(Type instanceType) | |
{ | |
return typeof(T).IsAssignableFrom(instanceType) && instanceType.IsAbstract; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment