Search code examples
c#jsonjson.netjson-deserialization

JSON.NET Deserialize Error converting to IList<string>


i have a json from Tika Rest Service with a list of message recipients. The list looks like this:

"Message-Recipient-Address": [
  "Mail1.Mail@mail.mail",
  "Mail2.Mail@mail.mail"]

In my model i have

[JsonProperty("Message-Recipient-Address")]
public IList<string> MailRecipientAddress { get; set; }

When trying to deserialize i get the following error message.

Error converting value "Mail1.Mail@mail.mail" to type 'System.Collections.Generic.IList`1[System.String]'. Path '[0].Message-Recipient-Address', line 1, position 319

This is the code of my deserializer (Restsharp)

public class TikaDeserializer : IDeserializer
{
    private Newtonsoft.Json.JsonSerializer serializer;

    public TikaDeserializer(Newtonsoft.Json.JsonSerializer serializer)
    {
        this.serializer = serializer;
    }

    public T Deserialize<T>(RestSharp.IRestResponse response)
    {
        var content = response.Content;

        using(var stringReader = new StringReader(content))
        {
            using(var jsonTextReader = new JsonTextReader(stringReader))
            {

                return serializer.Deserialize<T>(jsonTextReader);
            }
        }
    }

    public string DateFormat { get; set; }

    public string Namespace { get; set; }

    public string RootElement { get; set; }

    public static TikaDeserializer Default
    {
        get
        {
            return new TikaDeserializer(new Newtonsoft.Json.JsonSerializer()
            {
                NullValueHandling = NullValueHandling.Ignore,
            });
        }
    }
}

And here the Main Program Code

class Program
{
    static void Main(string[] args)
    {
        var request = new RestRequest("rmeta", Method.PUT);
        request.AddHeader("Accept", "application/json");
        request.AddParameter("application/octet-stream", File.ReadAllBytes(@"D:\Wienchol.msg"),ParameterType.RequestBody);
        var response = Execute<List<ParsedDocument>>(request);

    }



    public static T Execute<T>(RestRequest request) where T : new()
    {
        var client = Client(@"http://localhost:9998");
        client.AddHandler("application/json", TikaDeserializer.Default);
        client.AddHandler("text/json", TikaDeserializer.Default);
        client.AddHandler("text/x-json", TikaDeserializer.Default);
        client.AddHandler("text/javascript", TikaDeserializer.Default);
        client.AddHandler("*+json", TikaDeserializer.Default);

        var response = client.Execute<T>(request);

        if(response.ErrorException != null)
        {
            throw new SystemException(response.ErrorMessage);
        }

        return response.Data;
    }
}

Any clues what iam doing wrong, or why this is not working ? Thank you in advance, Stefan


Solution

  • Found a solution for my problem by writing a custom Json Converter:

    public class JsonStringListConverter: JsonConverter
    {
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
    
            if(reader.TokenType == JsonToken.Null)
            {
                return null;
            }
    
            List<string> items = new List<string>();
    
            if(reader.TokenType == JsonToken.String)
            {
    
                string value = reader.Value.ToString();
                items.Add(value);
            }
    
            if(reader.TokenType == JsonToken.StartArray)
            {
    
                reader.Read();
                do
                {
                    string value = reader.Value.ToString();
                    items.Add(value);
                    reader.Read();
                } while (reader.TokenType != JsonToken.EndArray);
            }
    
            return (items.Count = 0) ? null : items;
        }
    
    
    
        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(IList<string>));
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    

    And in my model

    [JsonProperty("Message-Recipient-Address")]
    [JsonConverter(typeof(JsonStringListConverter))]
    public IList<string> MailRecipientAddress { get; set; }