我有一个json文件,如下所示:
{
"tags": {
"t1": {
"description": "bar"
},
"t2": {
"description": {
"$ref": "./t2.md"
}
}
}
}
我想用Json.NET反序列化它,如下所示:
var baz = JsonConvert.DeserializeObject<Baz>(File.ReadAllText(@"baz.json"));
//...
internal class Baz
{
[JsonProperty("tags")]
internal Tags Tags;
}
internal class Tags: Dictionary<string, Tag>
{
}
internal class Tag
{
[JsonProperty("description")]
internal Description Description;
}
internal class Description // FIXME: can be string, Dictionary or List
{
}
如何定义Description
类,既可以是string
,也可以是Dictionary<string, string>
?我尝试过继承一个抽象方法,但反序列化程序总是返回null
。
您可以创建一个自定义反序列化程序:https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm
public class DescriptionConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return false;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
//If is string, return the string
return serializer.Deserialize(reader, objectType);
}
else
{
//If not string, try get the field '$ref'
var obj = JObject.Load(reader);
if (obj["$ref"] != null)
return obj["$ref"].ToString();
else
throw new InvalidOperationException("Invalid Json");
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后你可以在你的模型中指定这个转换器:
internal class Baz
{
[JsonProperty("tags")]
internal Tags Tags;
}
internal class Tags : Dictionary<string, Tag>
{
}
internal class Tag
{
[JsonProperty("description")]
[JsonConverter(typeof(DescriptionConverter))]
internal string Description;
}
最后,您可以反序列化json:
static void Main(string[] args)
{
string json = @"{
'tags': {
't1': {
'description': 'bar'
},
't2': {
'description': {
'$ref': './t2.md'
}
}
}
}";
var baz = JsonConvert.DeserializeObject<Baz>(json);
Console.WriteLine("t1 : " + baz.Tags["t1"].Description);
Console.WriteLine("t2 : " + baz.Tags["t2"].Description);
}
输出:
t1 : bar
t2 : ./t2.md