Home > Software engineering >  Newtonsoft can't deserialize object
Newtonsoft can't deserialize object

Time:04-28

I'm trying to deserialize my list of categories that I had on my web Api. But It won't return anything.

First it was returning this type of error

Cannot deserialize the JSON array (e.g. [1,2,3]) into type ' ' because type requires JSON object (e.g. {“name”:“value”}) to deserialize correctly

And I fixed it by not using await. Now on my variable jsonResponse returns everything just fine but the variable result is null.

Here is my code where the error is

// Generic Get Method
        private async Task<T> HttpGetAsync<T>(string url, string token)
        {
            T result = default(T);

            try
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                HttpResponseMessage response = httpClient.GetAsync(url).Result;
                HttpContent content = response.Content;

                if (response.IsSuccessStatusCode)
                {
                    var jsonResponse = await content.ReadAsStringAsync();
                    result = JsonConvert.DeserializeObject<T>(jsonResponse);
                }
                else
                {
                    throw new Exception(((int)response.StatusCode).ToString()   " - "   response.ReasonPhrase);
                }
            }
            catch (Exception ex)
            {
                one rror(ex.ToString());
            }

            return result;
        }

And here is what my json returns

{
    "data": [
        {
            "id": 1,
            "name": "Alianzas"
        },
        {
            "id": 2,
            "name": "Pendientes"
        },
        {
            "id": 3,
            "name": "Pulseras"
        },
        {
            "id": 4,
            "name": "Colgantes"
        },
        {
            "id": 5,
            "name": "Gargantillas"
        },
        {
            "id": 6,
            "name": "Relojes"
        }
    ],
    "meta": {
        "totalCount": 6,
        "pageSize": 20,
        "currentPage": 1,
        "totalPages": 1,
        "hasNextPage": false,
        "hasPreviousPage": false
    }
}

I don't know what is going on. Please help.

CodePudding user response:

It works for me, though I didn't replicate your HTTP stuff. So long as your code for that truly returns the json you posted into the jsonResponse string var, then I can't see a problem:

    class Program
    {
        static async Task Main(string[] args)
        {
            var x = await new Program().HttpGetAsync<SomeNamespace.SomeRoot>("", "");
        }

        private async Task<T> HttpGetAsync<T>(string url, string token)
        {
            T result = default(T);

            try
            {
                //httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                //HttpResponseMessage response = httpClient.GetAsync(url).Result;
               // HttpContent content = response.Content;

                if (/*response.IsSuccessStatusCode*/true)
                {
                    //var jsonResponse = await content.ReadAsStringAsync();

                    var jsonResponse = @"{
    ""data"": [
        {
            ""id"": 1,
            ""name"": ""Alianzas""
        },
        {
            ""id"": 2,
            ""name"": ""Pendientes""
        },
        {
            ""id"": 3,
            ""name"": ""Pulseras""
        },
        {
            ""id"": 4,
            ""name"": ""Colgantes""
        },
        {
            ""id"": 5,
            ""name"": ""Gargantillas""
        },
        {
            ""id"": 6,
            ""name"": ""Relojes""
        }
    ],
    ""meta"": {
        ""totalCount"": 6,
        ""pageSize"": 20,
        ""currentPage"": 1,
        ""totalPages"": 1,
        ""hasNextPage"": false,
        ""hasPreviousPage"": false
    }
}";
                    result = JsonConvert.DeserializeObject<T>(jsonResponse);
                }
                else
                {
                    //throw new Exception(((int)response.StatusCode).ToString()   " - "   response.ReasonPhrase);
                }
            }
            catch (Exception ex)
            {
                 //OnError(ex.ToString());
            }

            return result;
        }
    }

}

namespace SomeNamespace
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class SomeRoot
    {
        [JsonProperty("data")]
        public Datum[] Data { get; set; }

        [JsonProperty("meta")]
        public Meta Meta { get; set; }
    }

    public partial class Datum
    {
        [JsonProperty("id")]
        public long Id { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }
    }

    public partial class Meta
    {
        [JsonProperty("totalCount")]
        public long TotalCount { get; set; }

        [JsonProperty("pageSize")]
        public long PageSize { get; set; }

        [JsonProperty("currentPage")]
        public long CurrentPage { get; set; }

        [JsonProperty("totalPages")]
        public long TotalPages { get; set; }

        [JsonProperty("hasNextPage")]
        public bool HasNextPage { get; set; }

        [JsonProperty("hasPreviousPage")]
        public bool HasPreviousPage { get; set; }
    }

    public partial class SomeRoot
    {
        public static SomeRoot FromJson(string json) => JsonConvert.DeserializeObject<SomeRoot>(json, SomeNamespace.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this SomeRoot self) => JsonConvert.SerializeObject(self, SomeNamespace.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }

JSON receiver classes prepared by http://app.quicktype.io - no affiliation

CodePudding user response:

try to use List < Category > as T class

var result = await HttpGetAsync<List<Category>> (url,  token)

 ......

if (response.IsSuccessStatusCode)
 {
 var jsonResponse = await content.ReadAsStringAsync();
var jsonParsed=JObject.Parse(jsonResponse);
result =jsonResponse["data"].ToObject<T>();
}

class

    public partial class Category
    {
        [JsonProperty("id")]
        public long Id { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

       ....another properties
    }

or if you need Meta data, use Categories as T

var result = await HttpGetAsync<Categories> (url,  token)
....
var result = JsonConvert.DeserializeObject<T>(jsonResponse);

classes

public class Categories
{   
    [JsonProperty("data")]
    public List<Category> Data {get; set;}
    [JsonProperty("meta")]
    public Meta Meta {get; set;}
}


public partial class Meta
{
    [JsonProperty("totalCount")]
    public long TotalCount { get; set; }

    [JsonProperty("pageSize")]
    public long PageSize { get; set; }

    [JsonProperty("currentPage")]
    public long CurrentPage { get; set; }

    [JsonProperty("totalPages")]
    public long TotalPages { get; set; }

    [JsonProperty("hasNextPage")]
    public bool HasNextPage { get; set; }

    [JsonProperty("hasPreviousPage")]
    public bool HasPreviousPage { get; set; }
}
  • Related