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

Serialization 使用Json.Net反序列化以两种不同方式序列化的值,serialization,asp.net-core,json.net,deserialization,Serialization,Asp.net Core,Json.net,Deserialization,我有一个类似的课程: public class Values { public int BestValue { get; set; } public List<string> AllValues { get; set; } } 或 如何使用JsonConverter自动反序列化?(或任何其他解决方案。)为此,您需要创建一个: internal class ValuesConverter : JsonConverter { public override bo

我有一个类似的课程:

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

如何使用
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
{
公共覆盖布尔CanConvert(类型objectType)
{
返回类型(值)。IsAssignableFrom(objectType);
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var tokenType=reader.SkipComments().tokenType;
if(tokenType==JsonToken.Null)
返回null;
var value=existingValue作为值???(值)序列化程序.ContractResolver.ResolveContract(objectType.DefaultCreator();
if(tokenType==JsonToken.Date)
{
//避免将日期字符串转换为中所述的本地格式的恼人错误
// https://stackoverflow.com/questions/35166060/json-net-get-specific-json-date-value
value.AllValues=新列表{JToken.Load(reader).ToString(Formatting.None).Trim(“”)};
}
else if(tokenType.IsPrimitive())
{
value.AllValues=newlist{(string)JToken.Load(reader)};
}
其他的
{
序列化程序。填充(读取器、值);
}
返回值;
}
公共重写bool可以写入{get{return false;}}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
}
公共静态部分类JsonExtensions
{
公共静态JsonReader SkipComments(此JsonReader阅读器)
{
while(reader.TokenType==JsonToken.Comment&&reader.Read())
;
返回读取器;
}
公共静态bool IsPrimitive(此JsonToken令牌类型)
{
交换机(令牌类型)
{
案例JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
案例JsonToken.Boolean:
案例JsonToken。未定义:
案例JsonToken.Null:
案例JsonToken。日期:
案例JsonToken.Bytes:
返回true;
违约:
返回false;
}
}   
}
然后将其应用于您的类型,如下所示:

[JsonConverter(typeof(ValuesConverter))]
public class Values
{
    public int BestValue { get; set; }
    public List<string> AllValues { get; set; }
}
[JsonConverter(类型(值转换器))]
公共阶级价值观
{
公共int最佳值{get;set;}
公共列表所有值{get;set;}
}
或者,将其添加到中,然后修改设置,如中所示

注释-

  • 通过设置为false,可以在写入JSON时使用默认序列化

  • 当JSON值不是字符串时,用于通过默认反序列化填充
    值的内容

  • 通过使用构造
    对象,可以支持对
    的子类(如果有)进行反序列化


工作示例.Net fiddle。

谢谢!实际上我已经开始实现转换器,但我缺少“读取”中的代码“方法。关于如何实现的文档实际上并不十分清楚。。。
Populate
方法是我所缺少的!我还缺少注册部分,我认为属性足够注册它。哼,miread,属性足够:D我多次看到这些注册没有使用属性,我不太喜欢它们。
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; }
}