在 C# 中拦截 JSON 到 return 可空布尔值列表
intercept JSON in C# to return a list of nullable boolean
当我尝试从我的 JSON 拦截器中 return 一个可为 null 的布尔值列表时出现错误。
拦截器属性为:
[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 转换为列表(true、false、true ,false) 在 JSON 拦截器中
(实际上是NewtonSoft.Json)
如果您想将字符串值列表转换为具有 JsonConverter
class 的可空布尔值列表,我建议在转换器中使用 JArray
而不是试图直接处理 reader。这将允许您简化代码,同时避免您遇到的错误:
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();
}
}
Fiddle: 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; }
Fiddle: https://dotnetfiddle.net/Dp4N11
当我尝试从我的 JSON 拦截器中 return 一个可为 null 的布尔值列表时出现错误。 拦截器属性为:
[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 转换为列表(true、false、true ,false) 在 JSON 拦截器中 (实际上是NewtonSoft.Json)
如果您想将字符串值列表转换为具有 JsonConverter
class 的可空布尔值列表,我建议在转换器中使用 JArray
而不是试图直接处理 reader。这将允许您简化代码,同时避免您遇到的错误:
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();
}
}
Fiddle: 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; }
Fiddle: https://dotnetfiddle.net/Dp4N11