在 C# 中截获 JSON 以返回可为空的布尔值列表

本文关键字:列表 布尔值 返回 JSON | 更新日期: 2023-09-27 18:33:40

当我尝试从 JSON 拦截器返回可为空的布尔值列表时,我收到错误。拦截器属性为:

[JsonConverter(typeof(NullableBoolListDeSerializer))]
public List<bool?> ExemptBenefits { get; set; }

拦截器上的 ReadJSON 方法是:

 List<bool?> result = new List<bool?>();
        (reader as Newtonsoft.Json.Linq.JTokenReader).CurrentToken.ToList().ForEach(item =>
        {
            string value = (String)item.ToObject(typeof(String));
            switch (value.ToLower())
            {
                case "true":
                case "yes":
                case "1":
                    result.Add(true);
                    break;
                case "false":
                case "no":
                case "0":
                default:
                    result.Add(false);
                    break;
            }
        });
        return result;

正在提交的 JSON 是:

{
  "exemptBenefits": [
     "1"
  ],
  "_apiEndpoint": "/benefits/loan"
}

我得到的错误是:

Unexpected token when deserializing object: String. Path 'exemptBenefits[0]', line 1, position 187.

想知道如何转换字符串列表(例如"1","0")。true", "false") 从 JSON 到 JSON 拦截器中的列表(真、假、真、假)(其实是NewtonSoft.Json)

在 C# 中截获 JSON 以返回可为空的布尔值列表

如果要

将字符串值列表转换为具有JsonConverter类的可为空的布尔值列表,我建议您在转换器中使用JArray,而不是尝试直接与读取器打交道。 这将允许您简化代码,同时避免您遇到的错误:

class NullableBoolListDeSerializer : JsonConverter
{
    readonly string[] TrueStrings = { "true", "yes", "1" };
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<bool?>);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return JArray.Load(reader)
            .Children<JValue>()
            .Select(jv =>
            {
                string b = (string)jv;
                return b != null ? TrueStrings.Contains(b.ToLower()) : (bool?)null;
            })
            .ToList();
    }
    public override bool CanWrite
    {
        get { return false; }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

小提琴:https://dotnetfiddle.net/JaP5W7

当然,你实际上可以做得更好。 与其让你的转换器处理一个List<bool?>,不如让它只处理一个简单的bool?,例如:

class NullableBoolDeSerializer : JsonConverter
{
    readonly string[] TrueStrings = { "true", "yes", "1" };
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(bool?);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        string b = (string)reader.Value;
        return b != null ? TrueStrings.Contains(b.ToLower()) : (bool?)null;
    }
    public override bool CanWrite
    {
        get { return false; }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后,将 ExemptBenefits 属性声明上的 [JsonConverter] 属性换成[JsonProperty]属性,该属性的ItemConverterType参数设置为简化转换器。 然后,Json.Net 将为您创建列表。

[JsonProperty(ItemConverterType = typeof(NullableBoolDeSerializer))]
public List<bool?> ExemptBenefits { get; set; }

小提琴:https://dotnetfiddle.net/Dp4N11