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; }
}