使用Json.Net反序列化以两种不同方式序列化的值

时间:2018-04-15 19:59:04

标签: serialization asp.net-core json.net deserialization

我有一个类似于这个的课程:

public class Values
{
    public int BestValue { get; set; }
    public List<string> AllValues { get; set; }
}

这个类可以(因为历史记录)存储为<​​/ p>

"MyFirstValue"  /* if only one value */

{ "BestValue" : 0, "AllValues" : ["DefaultValue", "OtherValue"] }

如何使用JsonConverter自动反序列化? (或任何其他解决方案。)

1 个答案:

答案 0 :(得分:2)

您需要为此目的创建custom JsonConverter

internal class ValuesConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Values).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var tokenType = reader.SkipComments().TokenType;
        if (tokenType == JsonToken.Null)
            return null;
        var value = existingValue as Values ?? (Values)serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
        if (tokenType == JsonToken.Date)
        {
            // Avoid annoying bug that converts date strings to local format described in 
            // https://stackoverflow.com/questions/35166060/json-net-get-specific-json-date-value
            value.AllValues = new List<string> { JToken.Load(reader).ToString(Formatting.None).Trim('"') };
        }
        else if (tokenType.IsPrimitive())
        {
            value.AllValues = new List<string> { (string)JToken.Load(reader) };
        }
        else
        {
            serializer.Populate(reader, value);
        }
        return value;
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

public static partial class JsonExtensions
{
    public static JsonReader SkipComments(this JsonReader reader)
    {
        while (reader.TokenType == JsonToken.Comment && reader.Read())
            ;
        return reader;
    }

    public static bool IsPrimitive(this JsonToken tokenType)
    {
        switch (tokenType)
        {
            case JsonToken.Integer:
            case JsonToken.Float:
            case JsonToken.String:
            case JsonToken.Boolean:
            case JsonToken.Undefined:
            case JsonToken.Null:
            case JsonToken.Date:
            case JsonToken.Bytes:
                return true;
            default:
                return false;
        }
    }   
}

然后将其应用于您的类型,如下所示:

[JsonConverter(typeof(ValuesConverter))]
public class Values
{
    public int BestValue { get; set; }
    public List<string> AllValues { get; set; }
}

或者,将其添加到JsonSerializerSettings.Converters,然后修改您的设置,如 JsonSerializerSettings and Asp.Net Core 所示。

备注 -

工作样本.Net小提琴here