Home > Enterprise >  Upgrading JsonApiSerializer from 1.3.1 to 1.74 Issues with custom converter
Upgrading JsonApiSerializer from 1.3.1 to 1.74 Issues with custom converter

Time:11-05

I'm using this git repository JsonApiSerializer with a project and tying to update to the latest version 1.74. Everything works fine in version 1.3.1 but after upgrading to version 1.74 the custom converter cant get the Json to deserialize properly. I set a breakpoint on the converter put it never hits the ReadJson Method, instead it jumps out on the line

public override bool CanConvert(Type objectType) => false;

Is anyone familiar with JsonApiSerializer or customer converters able to see what the issue might be.

I receive this error.

JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.String' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly. To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'data[0].relationships.matches.data[0].type'.

Object I'm trying to deserialize to

public class PubgPlayer : PubgShardedEntity
    {
        [JsonProperty("Name")]
        public string Name { get; set; }

        [JsonProperty]
        public DateTime CreatedAt { get; set; }

        [JsonProperty]
        public string PatchVersion { get; set; }

        [JsonProperty]
        public string TitleId { get; set; }

        [JsonProperty("matches")]        
        [JsonConverter(typeof(RelationshipIdConverter))]
        public IEnumerable<string> MatchIds { get; set; }        
    }

This is the custom converter

public class RelationshipIdConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType) => false;
        public override bool CanWrite => false;

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,         JsonSerializer serializer)
        {
            //if the reader is not reading a relationship object just deserialize as normal.
            //This allows us to serialize and deserialize multiple times after converting from the   Json-API format
            if (reader.TokenType != JsonToken.StartObject)
                return serializer.Deserialize(reader, objectType);

            JToken jt = JToken.Load(reader);

            var dataToken = jt.SelectToken("data");
            
            if (objectType == typeof(string))
                return dataToken["id"].ToString();
            
            return dataToken.Select(x => (string)x["id"]).ToList();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { }
    }

Example Json

{
   "data":[
      {
         "type":"player",
         "id":"account.f96f1d482a5d4a21a4135f598f5a5c6a",
         "attributes":{
            "name":"Nomad_o7",
            "stats":null,
            "titleId":"pubg",
            "shardId":"steam",
            "patchVersion":""
         },
         "relationships":{
            "assets":{
               "data":[
                  
               ]
            },
            "matches":{
               "data":[
                  {
                     "type":"match",
                     "id":"e14ca749-3c19-49dd-9486-03de90669fa3"
                  },
                  {
                     "type":"match",
                     "id":"73dbca3e-eeee-44eb-9c43-3f71df0e02ae"
                  },
                  {
                     "type":"match",
                     "id":"e9f80ed0-1e78-4500-950f-174028fb73cc"
                  }
               ]
            }
         },
         "links":{
            "self":"https://api.pubg.com/shards/steam/players/account.f96f1d482a5d4a21a4135f598f5a5c6a",
            "schema":""
         }
      },
      {
         "type":"player",
         "id":"account.82bad0072f31455d8d9f8d834da2f2f3",
         "attributes":{
            "name":"TGLTN",
            "stats":null,
            "titleId":"pubg",
            "shardId":"steam",
            "patchVersion":""
         },
         "relationships":{
            "assets":{
               "data":[
                  
               ]
            },
            "matches":{
               "data":[
                  {
                     "type":"match",
                     "id":"4a6f064e-c292-4e9b-a3a6-bbaed891ce27"
                  },
                  {
                     "type":"match",
                     "id":"efd9434c-4116-4b56-815d-e30903b37c23"
                  },
                  {
                     "type":"match",
                     "id":"c1e56bff-db4c-470b-bb44-3c2068e33245"
                  },
                  {
                     "type":"match",
                     "id":"44d27efc-3cc6-4935-8bbe-702e4da44744"
                  },
                  {
                     "type":"match",
                     "id":"be3ebed3-9183-47f1-b4b0-40a2229dd5ff"
                  }                 
               ]
            }
         },
         "links":{
            "self":"https://api.pubg.com/shards/steam/players/account.82bad0072f31455d8d9f8d834da2f2f3",
            "schema":""
         }
      }
   ],
   "links":{
      "self":"https://api.pubg.com/shards/steam/players?filter[playerNames]=Nomad_o7,TGLTN"
   },
   "meta":{
      
   }
}

CodePudding user response:

I don't know how it could work before since you have a bug in your class

         [JsonProperty("matches")]        
        [JsonConverter(typeof(RelationshipIdConverter))]
        public IEnumerable<string> MatchIds { get; set; }    

but if you look at your json , you will see, that mathes is not a collection of strings, matches is a collection of objects

public partial class Relationships
    {
        [JsonProperty("assets")]
        public Assets Assets { get; set; }

        [JsonProperty("matches")]
        public Matches MatchIds { get; set; }
    }

    public partial class Matches
    {
        [JsonProperty("data")]
        public List<MatchesDatum> Data { get; set; }
    }

    public partial class MatchesDatum
    {
        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("id")]
        public Guid Id { get; set; }
    }

and IMHO you don't need any custom converter

  • Related