0

All,

I am using the JsonConverter as explained here: How to handle both a single item and an array for the same property using JSON.net

It works fine if the element is an array and it has more than 1 record, or if it is empty ([]). However, when the element has a single record, I run into a parsing error: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List. to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type

My classes as such:

    public class Qualifier
    {
        public string key { get; set; }
        public string message { get; set; }
    }

    public class Qualifiers
    {
        public List<Qualifier> qualifier { get; set; }
    }

    public class Response
    { 
        [JsonProperty("qualifiers", NullValueHandling = NullValueHandling.Ignore)]
        [JsonConverter(typeof(SingleOrArrayConverter<Qualifiers>))]
        public List<Qualifiers> qualifiers { get; set; }
    }

And below the JsonConverter:

   public class SingleOrArrayConverter<T> : JsonConverter
   {
    public override bool CanConvert(Type objecType)
    {
        return (objecType == typeof(List<T>));
    }

    public override object ReadJson(JsonReader reader, Type objecType, object existingValue,
        JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Array)
        {
            return token.ToObject<List<T>>();
        }
        return new List<T> { token.ToObject<T>() };
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

This is data that is throwing an error:

   {
     "response": {
      "qualifiers": {
       "qualifier": {
         "key": "does.not.match",
         "message": "Data Does Not Match"
      }
     }
    }
   }

Is there anything else I need to be doing to fix the single record error? Thanks in advance!

1moreLearner
  • 81
  • 10
  • 1
    It looks to me like you've only put the custom converter on one property, but you've got *two* list properties, *neither* of which are arrays in the JSON. I suggest you add it to `Qualifiers.qualifier` too. – Jon Skeet Mar 16 '23 at 15:58
  • @JonSkeet, sorry I don't follow what you are suggesting. Are you saying I should add the decorator with the class itself? Like, [JsonConverter(typeof(SingleOrArrayConverter))] public class Qualifiers { public List qualifier { get; set; } } – 1moreLearner Mar 16 '23 at 16:18
  • 1
    No, add it to the *property*, just as you've already done for `Response.qualifiers`. Basically, you've got two places where you want to be able to handle a single value as a list - so you need to do the same thing in both places. (Either that, or one of those `List<>` properties should be singular...) – Jon Skeet Mar 16 '23 at 16:20
  • 2
    The property `qualifiers` on the class `Qualifiers` needs the attribute `[JsonConverter(typeof(SingleOrArrayConverter))]` – Charlieface Mar 16 '23 at 16:38
  • Thank you @JonSkeet and @Charlieface!!! I can't believe all I needed was to add the attribute to the class. I appreciate! – 1moreLearner Mar 16 '23 at 16:59

0 Answers0