-2

I am facing the following scenario. A project of mine is throwing an event that contains the following object:

public class MyEvent : BaseEvent
{
   public long Id { get; set; }
   public Dictionary<string, long> Pairs { get; set; }
}

I received the event and read the data as byte[] on my receiver side. The current code I have to read any generic event is:

public static T Decode(byte[] data)
{
    var serializer = JsonSerializer.Create(new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Objects,
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    });

    using (var stream = new MemoryStream(data))
    {
        using (var sr = new StreamReader(stream, Encoding.UTF8))
        {
            var jr = new JsonTextReader(sr);
            var aux = Encoding.UTF8.GetString(data);
            return serializer.Deserialize(jr, typeof(T)) as T;
        }
    }
}

where T is my class MyEvent . Unfortunately the thrown exception is:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.Int64]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path 'OperationTimePairs', line 1, position 61.

The way I read it is that the object received doesn't have the correct format.. however if I try to read it through var aux = Encoding.UTF8.GetString(data); I can see that the structure is the correct one. Any idea how can I fix this? Thanks!

EDIT:

Json Example:

{  
   "Timestamp":"\/Date(1540996292134)\/",
   "Pairs":[  
      {  
         "Key":"first time",
         "Value":28
      },
      {  
         "Key":"second time",
         "Value":30
      },
      {  
         "Key":"third time",
         "Value":101
      },
      {  
         "Key":"operation time",
         "Value":231
      }
   ],
   "Id":123637
}
7
  • Can you please post a sample json? What do you get after var aux = Encoding.UTF8.GetString(data);? Commented Oct 31, 2018 at 14:53
  • Also, could you please post the class definition of BaseEvent? Commented Oct 31, 2018 at 14:54
  • It's giving you a pretty explanatory error message. Instead of using a Dictionary use a List<T> of a custom class called Pair which contains two primitive types of string and long Commented Oct 31, 2018 at 14:54
  • 1
    To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. Commented Oct 31, 2018 at 14:59
  • @NewContributor not a duplicate, check out my edit where I post an example of JSON. Mine is a single object, not an array Commented Oct 31, 2018 at 15:04

1 Answer 1

1

I think that your classes don't match the json string structure.

Given the following json string:

{  
   "Timestamp":"\/Date(1540996292134)\/",
   "Pairs":[  
      {  
         "Key":"first time",
         "Value":28
      },
      {  
         "Key":"second time",
         "Value":30
      },
      {  
         "Key":"third time",
         "Value":101
      },
      {  
         "Key":"operation time",
         "Value":231
      }
   ],
   "Id":123637
}

You can change your models to match the json structure, something like this:

public class MyEvent : BaseEvent
{
    public long Id { get; set; }
    public List<KeyValuePair<string, long>> Pairs { get; set; }

    [JsonIgnore]
    public Dictionary<string, long> PairsDictionary
    {
        get
        {
            if (Pairs == null)
            {
                return new Dictionary<string, long>();
            }

            return Pairs.ToDictionary(pair => pair.Key, pair => pair.Value);
        }
    }
}

public class BaseEvent
{
    public DateTime Timestamp { get; set; }
}

Please note:

  • PairsDictionary is a non-serializable property based on Pairs
  • Given that you didn't provide the class definition of BaseEvent, I will assume that it has 1 property only

Testing the deserialization:

string json = @"{  
""Timestamp"":""\/Date(1540996292134)\/"",
""Pairs"":[  
    {  
     ""Key"":""first time"",
     ""Value"":28
    },
    {  
     ""Key"":""second time"",
     ""Value"":30
    },
    {  
     ""Key"":""third time"",
     ""Value"":101
    },
    {  
     ""Key"":""operation time"",
     ""Value"":231
    }
],
""Id"":123637
}";

MyEvent eventData = JsonConvert.DeserializeObject<MyEvent>(json);

Or as an alternative (using generics):

T data = JsonConvert.DeserializeObject(json, typeof(T)) as T;
Sign up to request clarification or add additional context in comments.

1 Comment

PairsDictionary is a non-serializable property based on Pairs here is the answer! that's all I needed to know :) thanks a lot!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.