我有这样的json:
{
"_id":{
"$oid":"5b7bc6acc223c11047485dd5"
},
"id":"28679e7d-0bca-40b0-b033-044df2bb1b47",
"type":"some string"
}
以及此类:
public class Foo
{
private readonly JObject _json;
internal Foo(JObject data)
{
_json = data;
}
public override Guid Id => (_json["id"]).ToObject<Guid>();
public override string Type => _json["type"]?.ToString();
}
我想将此字符串反序列化为Foo
实例。我有以下反序列化器:
public class FooConverter : JsonConverter<Foo>
{
public override void WriteJson(JsonWriter writer, Foo value, JsonSerializer serializer)
{
writer.WriteRaw(value.GetJsonData().ToString());
}
public override Foo ReadJson(JsonReader reader, Type objectType, Foo existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var obj = JObject.Load(reader); // Here's an exception
return new Foo(obj);
}
}
如您所见,我的json有_id
字段,Foo
没有。当我打电话
JsonConvert.DeserializeObject<Foo>(jsonString);
我收到此异常:
'Newtonsoft.Json.JsonReaderException:'解析值时遇到意外字符:O。路径'_id',第1行,位置10。''
是否可以避免此异常并正确加载json?
答案 0 :(得分:1)
以下json字符串
{
"_id":{
"$oid":"5b7bc6acc223c11047485dd5"
},
"id":"28679e7d-0bca-40b0-b033-044df2bb1b47",
"type":"some string"
}
可以映射到以下类别:
public class Foo
{
[JsonProperty("_id")]
public FooId FooId { get; set; }
[JsonProperty("id")]
public Guid Id { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
}
public class FooId
{
[JsonProperty("$oid")]
public string Oid { get; set; }
}
测试代码:
using System;
using Newtonsoft.Json;
class Program
{
static void Main(string[] args)
{
string json = @"{
""_id"":{
""$oid"":""5b7bc6acc223c11047485dd5""
},
""id"":""28679e7d-0bca-40b0-b033-044df2bb1b47"",
""type"":""some string""
}";
var foo = JsonConvert.DeserializeObject<Foo>(json);
Console.Read();
}
}
答案 1 :(得分:0)
如果除了private readonly JObject _json;
和Id
的获取者之外,不需要其他Type
属性,可以通过如下方法直接反序列化为Foo
来简化代码: / p>
更改您的Foo
班级:
public class Foo
{
[JsonProperty("id")]
public override Guid Id {get;set;}
[JsonProperty("type")]
public override string Type {get;set;}
}
需要JsonProperty
属性,因为json字符串中的元素键与Foo
类中的元素键不同(区分大小写)。
然后您可以像这样反序列化json:
var json = "some json";
var foo = JsonConvert.DeserializeObject<Foo>(json);
json _id
元素只是被忽略。
这样做的时候,您可以省略创建自定义转换器FooConverter
的过程,而您的Foo
类更简洁。