gpt4 book ai didi

c# - 数字到 bool 值的自动转换 - 从 Newtonsoft 迁移到 System.Text.Json

转载 作者:行者123 更新时间:2023-12-04 07:17:57 25 4
gpt4 key购买 nike

我不小心通过切换到 System.Text.Json 在我的 API 中引入了重大更改在我的 ASP.NET Core 应用程序中。我有一个客户端正在发送 JSON 文档并使用数字 10用于 bool 字段而不是 truefalse :

// What they're sending.
{ "Active": 1 }

// What they should be sending.
{ "Active": true }
Newtonsoft.Json库通过将数字转换为 bool 值来自动处理此问题(0 = false,其他所有内容 = true),但 System.Text.Json不这样做;它会引发异常。这意味着我的 API 端点突然停止为发送 1 的愚蠢客户端工作。的和 0的!
我似乎在迁移指南中找不到任何提及。我想将行为恢复到 Newtonsoft 处理它的方式,但我不确定是否有一个标志可以在我看不到的地方启用它,或者我是否必须编写自定义转换器。
有人可以帮我恢复像 Newtonsoft 那样的行为吗?

下面是一些代码来演示这个问题:
using System;

string data = "{ \"Active\": 1 }";

try
{
OutputState s1 = System.Text.Json.JsonSerializer.Deserialize<OutputState>(data);
Console.WriteLine($"OutputState 1: {s1.Active}");
}
catch (Exception ex)
{
Console.WriteLine($"System.Text.Json failed: {ex.Message}");
}

try
{
OutputState s2 = Newtonsoft.Json.JsonConvert.DeserializeObject<OutputState>(data);
Console.WriteLine($"OutputState 2: {s2.Active}");
}
catch (Exception ex)
{
Console.WriteLine($"Newtonsoft.Json failed: {ex.Message}");
}

public record OutputState(bool Active);
也是交互式游乐场的 .NET fiddle : https://dotnetfiddle.net/xgm2u7

最佳答案

您可以创建自定义 JsonConverter<bool> 模拟 Json.NET 的逻辑 JsonReader.ReadAsBoolean() :

public class BoolConverter : JsonConverter<bool>
{
public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options) =>
writer.WriteBooleanValue(value);

public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
reader.TokenType switch
{
JsonTokenType.True => true,
JsonTokenType.False => false,
JsonTokenType.String => bool.TryParse(reader.GetString(), out var b) ? b : throw new JsonException(),
JsonTokenType.Number => reader.TryGetInt64(out long l) ? Convert.ToBoolean(l) : reader.TryGetDouble(out double d) ? Convert.ToBoolean(d) : false,
_ => throw new JsonException(),
};
}
通过将其添加到 JsonSerializerOptions.Converters 来使用:
var options = new JsonSerializerOptions
{
Converters = { new BoolConverter() },
};
var s1 = System.Text.Json.JsonSerializer.Deserialize<OutputState>(data, options);
演示 fiddle #1 here .
笔记:
  • Json.NET 会自动尝试将字符串反序列化为 bool使用 bool.TryParse() 它使用有序且不区分大小写的比较进行解析。只需检查例如 Utf8JsonReader.ValueTextEquals("true") 不会模拟 Newtonsoft 的大小写不变性。
  • Json.NET 支持将整数和浮点数反序列化为 bool通过尝试将值标记解析为 longdouble (或 decimal 当设置 FloatParseHandling.Decimal 时)然后调用 Convert.ToBoolean() 结果上。转换器模拟此逻辑。
  • 我的 BoolConverter<bool> 可能存在一些边界条件和 Json.NET 的行为不同,特别是对于溢出或舍入接近零的情况。
  • 如果您还需要支持将数字反序列化为 bool? , 抢 NullableConverterFactory来自 this answerHow to deserialize an empty string to a null value for all `Nullable<T>` value types using System.Text.Json?并将其添加到转换器中,如下所示:
     var options = new JsonSerializerOptions
    {
    Converters = { new BoolConverter(), new NullableConverterFactory() },
    };
    这个转换器工厂还修复了从 Newtonsoft 到 System.Text.Json 的另一个模糊的重大变化,即前者将反序列化一个空的 JSON 字符串 ""给任何 Nullable<T>但后者不会。
    演示 fiddle #2 here .
  • 关于c# - 数字到 bool 值的自动转换 - 从 Newtonsoft 迁移到 System.Text.Json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68682450/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com