我有课Foo
和它的FooConverter
定义如下:
[JsonConverter(typeof(FooConverter))]
public class Foo
{
public string Something { get; set; }
}
public class FooConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(((Foo)value).Something);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var str = reader.ReadAsString();
if (str == null)
{
throw new JsonSerializationException();
}
// return new Foo {Something = serializer.Deserialize<string>(reader)};
return new Foo {Something = str};
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Foo);
}
}
序列化工作正常。但反序列化时:
var foo = JsonConvert.DeserializeObject<Foo>("\"something\"");
它抛出JsonSerializationException
因为reader.ReadAsString
一片空白。
但我不明白为什么一定要这样null
... reader.ReadAsString
如果我像这样手动执行此操作,则可以完美找到:
var reader = new JsonTextReader(new StringReader("\"something\""));
var str = reader.ReadAsString(); // str is now `something` NOT null
虽然我可以修复FooConverter
通过使用serializer.Deserialize<string>(reader)
in ReadJson
,我还是想明白为什么reader.ReadAsString
失败了FooConverter.ReadJson
.
你的问题是,根据文档, JsonReader.ReadAsString()
:
读到next来自源的 JSON 令牌作为字符串。
然而,当JsonConverter.ReadJson()被调用时,读取器已经定位到与正在反序列化的对象相对应的第一个 JSON 标记。因此,通过调用ReadAsString()
您丢弃该值并尝试读取流中的下一个标记 - 但没有,因此您抛出异常。
此外,在年底ReadJson()
您的代码必须将读取器定位到与正在转换的对象对应的最后一个 JSON 标记。因此,在 JSON 只是一个原语的情况下,读者根本不应该先进。
保证读者始终正确定位的简单方法ReadJson()
是打电话JToken.Load()。这始终使读取器位于已加载令牌的末尾。之后,您可以检查加载的内容是否符合预期。例如,如果 JSON 中有一个需要字符串的对象,而不是让读取器处于错误的位置,那么转换器应该抛出异常,而不是让读取器处于错误的位置。
StringIdConverter
from Json.Net:将属性序列化/反序列化为值,而不是对象举了一个例子。您可以按如下方式修改它:
public class FooConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var token = JToken.Load(reader);
if (!(token is JValue))
throw new JsonSerializationException("Token was not a primitive");
return new Foo { Something = (string)token };
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)