System.Text.Json - 反序列化可以是空字符串或 class 的对象
System.Text.Json - Deserialize object that can be either an empty string or a class
我正在使用 System.Text.Json
反序列化一些 json。 (更具体地说,this call 来自 Last.fm API json 格式)
我试图反序列化的 json 有一种非常规的方式来处理某些对象的空值,例如当它为空时我得到这个:
"tags": "",
当它有值时像这样:
"tags": {
"tag": [
{
"name": "classic rock",
"url": "https://www.last.fm/tag/classic+rock"
},
{
"name": "rock",
"url": "https://www.last.fm/tag/rock"
}
]
}
我的 C# class 看起来像这样:
public class Artist
{
public Tags Tags { get; set; }
}
public class Tags
{
public Tag[] Tag { get; set; }
}
public class Tag
{
public string Name { get; set; }
public string Url { get; set; }
}
在实际尝试反序列化之前如何检查对象是否为空字符串?
当我尝试反序列化它时:
var deserializedObject = JsonSerializer.Deserialize<T>(requestBody);
它抛出 System.Text.Json.JsonException: The JSON value could not be converted to FMBot.LastFM.Domain.Models.Tags. Path: $.artist.tags
错误。
这个调用曾经在值实际为 null
时起作用,但现在它是一个空字符串,它被破坏了,我无法找到解决方案。
解决此问题的一个简单方法是将 Tags
属性 的类型更改为 dynamic
。
public class Artist
{
public dynamic Tags { get; set; }
}
然后您可以检查 Tags is Tag[]
或 Tags is string
并采取相应措施。别忘了检查它是否不是以上两者(并且可能会抛出)。
我会为此任务使用自定义转换器。例如:
public class TagsConverter : JsonConverter<Tags>
{
public override Tags Read(ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
// If the token is a string, return null
if(reader.TokenType == JsonTokenType.String)
{
return null;
}
// Skip over the object and property name
reader.Read(); // Object
reader.Read(); // Property name
// Read the tags array
var tags = JsonSerializer.Deserialize<Tag[]>(ref reader, options);
reader.Read(); // Object
return new Tags { Tag = tags};
}
public override void Write(Utf8JsonWriter writer, Tags value,
JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
并像这样使用它:
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
Converters = { new TagsConverter() }
};
var deserializedObject = JsonSerializer.Deserialize<Artist>(requestBody, options );
我正在使用 System.Text.Json
反序列化一些 json。 (更具体地说,this call 来自 Last.fm API json 格式)
我试图反序列化的 json 有一种非常规的方式来处理某些对象的空值,例如当它为空时我得到这个:
"tags": "",
当它有值时像这样:
"tags": {
"tag": [
{
"name": "classic rock",
"url": "https://www.last.fm/tag/classic+rock"
},
{
"name": "rock",
"url": "https://www.last.fm/tag/rock"
}
]
}
我的 C# class 看起来像这样:
public class Artist
{
public Tags Tags { get; set; }
}
public class Tags
{
public Tag[] Tag { get; set; }
}
public class Tag
{
public string Name { get; set; }
public string Url { get; set; }
}
在实际尝试反序列化之前如何检查对象是否为空字符串?
当我尝试反序列化它时:
var deserializedObject = JsonSerializer.Deserialize<T>(requestBody);
它抛出 System.Text.Json.JsonException: The JSON value could not be converted to FMBot.LastFM.Domain.Models.Tags. Path: $.artist.tags
错误。
这个调用曾经在值实际为 null
时起作用,但现在它是一个空字符串,它被破坏了,我无法找到解决方案。
解决此问题的一个简单方法是将 Tags
属性 的类型更改为 dynamic
。
public class Artist
{
public dynamic Tags { get; set; }
}
然后您可以检查 Tags is Tag[]
或 Tags is string
并采取相应措施。别忘了检查它是否不是以上两者(并且可能会抛出)。
我会为此任务使用自定义转换器。例如:
public class TagsConverter : JsonConverter<Tags>
{
public override Tags Read(ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
// If the token is a string, return null
if(reader.TokenType == JsonTokenType.String)
{
return null;
}
// Skip over the object and property name
reader.Read(); // Object
reader.Read(); // Property name
// Read the tags array
var tags = JsonSerializer.Deserialize<Tag[]>(ref reader, options);
reader.Read(); // Object
return new Tags { Tag = tags};
}
public override void Write(Utf8JsonWriter writer, Tags value,
JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
并像这样使用它:
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
Converters = { new TagsConverter() }
};
var deserializedObject = JsonSerializer.Deserialize<Artist>(requestBody, options );