kaf*_*fka 3 c# json jsonconverter system.text.json
我有这个jsonconverter,它需要将给定的属性值转换为小数或长整型,具体取决于该值 - 但我似乎无法确定属性值何时为小数或长整型,因为 tokentype 只能检测数字。 .我该如何解决这个问题?
public override IDictionary<string, object> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
IDictionary<string, object> output = new Dictionary<string, object>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
string propertyName = reader.GetString();
reader.Read();
object? propertyValue = null;
switch (reader.TokenType)
{
case JsonTokenType.Number:
propertyValue = reader.GetInt64(); // or could be a decimal for where I should reader.GetDecimal()
break;
case JsonTokenType.String:
if (reader.TryGetDateTime(out DateTime value))
{
propertyValue = value;
}
else
{
propertyValue = reader.GetString();
}
break;
case JsonTokenType.True:
case JsonTokenType.False:
propertyValue = reader.GetBoolean();
break;
}
output.Add(propertyName, propertyValue);
}
return output;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用Utf8JsonReader.TryGetInt64(out long value)和Utf8JsonReader.TryGetDecimal(out decimal value)来测试当前值是否可以成功解析为 along或 a decimal。
因此,您修改后的Read()方法应如下所示:
public override IDictionary<string, object> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// Assert we are currently at the beginning of an object
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException(string.Format("Unexpected token {0}", reader.TokenType));
IDictionary<string, object> output = new Dictionary<string, object>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
string propertyName = reader.GetString()!;
reader.Read();
object? propertyValue;
switch (reader.TokenType)
{
case JsonTokenType.Number:
if (reader.TryGetInt64(out var l))
propertyValue = l;
else if (reader.TryGetDecimal(out var d))
propertyValue = d;
else
{
// Either store the value as a string, or throw an exception.
using var doc = JsonDocument.ParseValue(ref reader);
propertyValue = doc.RootElement.ToString();
throw new JsonException(string.Format("Cannot parse number: {0}", propertyValue));
}
break;
case JsonTokenType.String:
if (reader.TryGetDateTime(out var dt))
propertyValue = dt;
else
propertyValue = reader.GetString();
break;
case JsonTokenType.True:
case JsonTokenType.False:
propertyValue = reader.GetBoolean();
break;
case JsonTokenType.Null:
propertyValue = null;
break;
default:
// An unexpected token type such as an object or array.
// You must either skip it or throw an exception.
reader.Skip();
propertyValue = null;
throw new JsonException(string.Format("Unexpected token {0}", reader.TokenType));
//break;
}
// Since your converter is of type IDictionary<string, object> I assume you don't want to allow null values.
// If you do want to allow null values you should declare it as IDictionary<string, object?>
if (propertyValue == null)
throw new JsonException("null value");
output.Add(propertyName, propertyValue);
}
return output;
}
Run Code Online (Sandbox Code Playgroud)
笔记:
虽然Utf8JsonReader会在格式错误的 JSON 上引发异常,但转换器有责任处理任何类型的有效值标记,并在任何不支持的值类型上引发异常。
我修改了转换器,以根据需要抛出意外值类型的异常。
由于您似乎启用了可空引用类型检查propertyValue,因此我修改了您的代码以在为空时抛出异常。如果您想允许 null 属性值,您应该将转换器声明为JsonConverter<IDictionary<string, object?>>.
您的转换器仅处理原始值。如果您想扩展它以将嵌套对象反序列化为嵌套Dictionary<string, object>值,并将嵌套数组反序列化为嵌套List<object>值,您可以查看ObjectAsPrimitiveConverterC # - Deserializingnested json tonested Dictionary<string, object>的答案。
演示小提琴在这里。
| 归档时间: |
|
| 查看次数: |
2164 次 |
| 最近记录: |