I am getting an error when I try to return a list of nullable boolean from my JSON interceptor. The interceptor attribute is:
[JsonConverter(typeof(NullableBoolListDeSerializer))]
public List<bool?> ExemptBenefits { get; set; }
The ReadJSON method on the interceptor is:
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;
The JSON being submitted is:
{
"exemptBenefits": [
"1"
],
"_apiEndpoint": "/benefits/loan"
}
The error I am getting is:
Unexpected token when deserializing object: String. Path 'exemptBenefits[0]', line 1, position 187.
Wondering how to convert a list of strings (eg "1","0"."true", "false") from JSON to a List (true,false,true,false) in a JSON interceptor (actually it is NewtonSoft.Json)
If you want to convert a list of string values into a list of nullable boolean values with a JsonConverter
class, I would recommend using a JArray
inside the converter instead of trying to deal with the reader directly. This will allow you to simplify your code while also avoiding the error you encountered:
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
Of course, you can actually do better than that. Instead of making your converter handle a List<bool?>
, make it handle just a simple bool?
instead, eg:
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();
}
}
Then, swap out the [JsonConverter]
attribute on your ExemptBenefits
property declaration for a [JsonProperty]
attribute that has its ItemConverterType
parameter set to the simplified converter. Json.Net will then handle creating the list for you.
[JsonProperty(ItemConverterType = typeof(NullableBoolDeSerializer))]
public List<bool?> ExemptBenefits { get; set; }
Fiddle: https://dotnetfiddle.net/Dp4N11
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.