Given the following structure:
"meta": {
"pagination": {
"total": 378,
"count": 50,
"per_page": 50,
"current_page": 2,
"total_pages": 8,
"links": {
"previous": "https://myapi.com.br/api/clients?page=1",
"next": "https://myapi.com.br/api/clients?page=3"
}
}
Sometimes the value of the property "links" is returned as an empty array.
"meta": {
"pagination": {
"total": 14,
"count": 14,
"per_page": 50,
"current_page": 1,
"total_pages": 1,
"links": []
}
}
So I created a type inherited from JsonConverter to set in my class property.
This is where I don't know how to proceed.
public class LinksJsonConverter : JsonConverter
{
public override bool CanWrite => false;
public override bool CanConvert(Type objectType)
=> objectType == typeof(Links);
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
var links = new Links();
if (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.EndArray)
return links; // try return null
JObject jo = JObject.Load(reader);
links.Previous = jo["Previous"]?.ToString() ?? string.Empty;
links.Next = jo["Next"]?.ToString();?? string.Empty;
return links;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
=> ...
}
The classes:
public class Links
{
public string Previous { get; set; }
public string Next { get; set; }
}
public class Pagination
{
public int Total { get; set; }
public int Count { get; set; }
[JsonProperty("per_page")]
public int PerPage { get; set; }
[JsonProperty("current_page")]
public int CurrentPage { get; set; }
[JsonProperty("total_pages")]
public int TotalPages { get; set; }
[JsonConverter(typeof(LinksJsonConverter))]
public Links Links { get; set; }
}
The error when I try to convert from empty "links" property. When the value is an empty array:
Message:
Test method IntegrationDownloaderServiceTests.ShouldProcessResultNfe threw exception:
Newtonsoft.Json.JsonSerializationException: Unexpected token when deserializing object:
EndArray. Path 'meta.pagination.links', line 123, position 17.
How to solve this case?
CodePudding user response:
in first step deserialize link as object :
public class Pagination
{
public int total { get; set; }
public int count { get; set; }
public int per_page { get; set; }
public int current_page { get; set; }
public int total_pages { get; set; }
public object links { get; set; }
}
public class Meta
{
public Pagination pagination { get; set; }
}
public class Root
{
public Meta meta { get; set; }
}
then check links type: (this)
public static class TypeExtensions
{
public static bool IsArrayOf<T>(this Type type)
{
return type == typeof (T[]);
}
}
and decide convert object to array or not.
CodePudding user response:
I probably wasn't clear enough about my question.
I want to ignore the array value (at least for now) until the day it makes sense.
In the documentation of this API I didn't find references about it.
I will try to contact the developer.
This way it worked:
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartObject)
{
JObject jo = JObject.Load(reader);
var links = new Links
{
Previous = jo["previous"]?.Value<string>() ?? string.Empty,
Next = jo["next"]?.Value<string>() ?? string.Empty
};
return links;
}
else if (reader.TokenType == JsonToken.StartArray)
{
reader.Skip();
}
return null;
}