skip to Main Content

The API currently return two types of json string (the type field always be string but the data field may be string or list or int):

For example Type 1:

{
    "type": "error",
    "data": "error message"
}

Type 2:

{
    "type": "success",
    "data": [
        {
            "id": 1,
            "title": "tortor at auctor urna nunc",
            "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
        },
        {
            "id": 2,
            "title": "gravida rutrum quisque non tellus",
            "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
        }
        ]
}

I have the following class for mapping the json string:

class ResponseData
{
    [JsonPropertyName("type")]
    public string Type { get; set; }

    [JsonPropertyName("data")]
    public string Data { get; set; }
}

I would like to deserialize the json to ResponseData and print out the text in data field, for example:

var response = await httpClient.GetAsync(url);
var responseData = await response.Content.ReadFromJsonAsync<ResponseData>();
Debug.WriteLine(responseData.Data);

If the API returns the json type 1, the code works fine. but if it returns the json type 2, it throws the following error message:

Exception thrown: 'System.Text.Json.JsonException' in System.Private.CoreLib.dll
The JSON value could not be converted to System.String. Path: $.data | LineNumber: 0 | BytePositionInLine: 32.: Error

Any idea to solve this issue?
Thanks.

I would expect if the API returns the json type 2, at least the following json string can be saved into responseData.Data as string:

"[
    {
        "id": 1,
        "title": "tortor at auctor urna nunc",
        "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
    }
]"

so that I can deserialize the responseData.Data json string into another object

var dataList = JsonSerializer.Deserialize<DataList>(responseData.Data);

2

Answers


  1. The problem is in both cases you’re trying to deserialize "data" to a string (because you’ve defined the property Data in your ResponseData class to be of type string), but in the second case "data" is a json array, which can’t be automatically converted to a string.

    I’m not sure your design is the optimal approach in the first place if I may say so, but if you want to get it working as is, more or less, you could change Data’s type to obejct.

    Here is a quick demo of the idea using Newtonsoft:

    string example1 = @"{
        ""type"": ""error"",
        ""data"": ""error message""
    }";
    
    string example2 = @"{
        ""type"": ""success"",
        ""data"": [
            {
                ""id"": 1,
                ""title"": ""tortor at auctor urna nunc"",
                ""content"": ""Lorem ipsum dolor sit amet, consectetur adipiscing elit.""
            },
            {
                ""id"": 2,
                ""title"": ""gravida rutrum quisque non tellus"",
                ""content"": ""Lorem ipsum dolor sit amet, consectetur adipiscing elit.""
            }
            ]
    }";
    
    var response1 = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseData>(example1);
    Console.WriteLine(response1.Data.ToString());
    
    var response2 = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseData>(example2);
    Console.WriteLine(response2.Data.ToString());
    
    class ResponseData
    {
        [JsonPropertyName("type")]
        public string Type { get; set; }
    
        [JsonPropertyName("data")]
        public object Data { get; set; }
    }
    
    Login or Signup to reply.
  2. you can try this code

        var json = await response.Content.ReadAsStringAsync();
    
        var jn = JsonNode.Parse(json).AsObject();
        ResponseData responseData = jn.Deserialize<ResponseData>();
    
        if (responseData.Type == "success")
            responseData.Data = jn["data"].Deserialize<List<Datum>>();
        else
            responseData.ErrorMessage = jn["data"].GetValue<string>();
    

    classes

    public partial class ResponseData
    {
        [JsonPropertyName("type")]
        public string Type { get; set; }
    
        public string ErrorMessage { get; set; }
    
        public List<Datum> Data { get; set; }
    }
    
    public partial class Datum
    {
        [JsonPropertyName("id")]
        public long Id { get; set; }
    
        [JsonPropertyName("title")]
        public string Title { get; set; }
    
        [JsonPropertyName("content")]
        public string Content { get; set; }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search