-2

I am trying to deserialize a JSON response, but I am doing something wrong when creating the data models.

I deserialize normally with EventsData resultJSON = JsonConvert.DeserializeObject<EventsData>(jsonText);

JSON contains list of events such as:

{
   "@event_no":"6924",
   "@name":"REDACTED",
    "Show":{
        "@show_no":"1",
        "@show_datetime":"2007-04-05 15:00:00"
     }
 },
 {
    "@event_no":"6925",
    "@name":"REDACTED",
     "Show":{
         "@show_no":"1",
         "@show_datetime":"2007-04-15 15:00:00"
      }
 }

My data model:

public class Show
    {
        [JsonProperty("@show_no")]
        public string show_no { get; set; }
        [JsonProperty("@show_datetime")]
        public string show_datetime { get; set; }
    }

public class Event
{
    [JsonProperty("@event_no")]
    public string event_no { get; set; }
    [JsonProperty("@name")]
    public string name { get; set; }
    public Show Show { get; set; }
}

public class Events
    {
        public List<Event> Event { get; set; }
    }

    public class EventsData
    {
        public Events Events { get; set; }
    }

However, when I am trying to deserialize I get the following error:

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'VM_Models.Show' 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.

What exactly am I doing wrong? If I make the Show property dynamic instead of class Show then it works

UPDATE: I did find in the data sometimes there are more than one shows:

{ "@event_no":"54535", "@name":"REDACTED", "Show": [ { "@show_no": "1", "@show_datetime": "2009-05-06 19:00:00" }, { "@show_no": "2", "@show_datetime": "2009-05-07 19:00:00" }, { "@show_no": "3", "@show_datetime": "2009-05-08 19:00:00" }, { "@show_no": "4", "@show_datetime": "2009-05-09 19:00:00" }, { "@show_no": "5", "@show_datetime": "2009-05-10 19:00:00" } ] }

crystyxn
  • 1,411
  • 4
  • 27
  • 59
  • You don't show `EventsData`. And there is missing information in your JSON fragment that may be useful. It may be that the model is out of sync with the full data somewhere. – Colin Mackay Mar 04 '21 at 14:38
  • you are right I just attempted to simplify a bit. Also I did discover that at some point one event contains two shows, will update OP – crystyxn Mar 04 '21 at 14:39
  • 2
    Your JSON isn't well-formed, it's lacking outer braces `[` and `]`. Upload it to https://jsonlint.com/ and you will get an error *`Error: Parse error on line 8:`*.Assuming it has those you must deserialize to a `List` as shown in [Cannot deserialize the JSON array (e.g. `[1,2,3]`) into type ' ' because type requires JSON object (e.g. {“name”:“value”}) to deserialize correctly)](https://stackoverflow.com/q/22557559/3744182). In fact this looks to be a duplicate, agree? – dbc Mar 04 '21 at 14:42
  • I am converting from XML to JSON maybe it gets lost in the process hmm – crystyxn Mar 04 '21 at 14:43
  • This JSON is definitely not valid. Do you have an outer object? – Charlieface Mar 04 '21 at 14:45
  • 1
    XML doesn't have the concept of an array, so when converting from XML to JSON repeating elements will sometimes get converted to an array, and sometimes not, depending on whether the repeating element occurs exactly once. To handle that in a generic way, use `List` properties for possibly repeating elements, and use `SingleOrArrayListConverter ` from [this answer](https://stackoverflow.com/a/53771970/3744182) to [How to handle both a single item and an array for the same property using JSON.net](https://stackoverflow.com/q/18994685/3744182). – dbc Mar 04 '21 at 14:46
  • "Sometimes" there is more than one show is going to be a problem. Your JSON should be consistent, so if there can be more than one show, you should use an array in the JSON and the `Show` property of the event should be a collection of some kind (e.g., array or list). – Jack A. Mar 04 '21 at 14:46
  • 1
    You are right. I ditched the XML to JSON to Object conversion and did XML straight to Object and it worked way better. – crystyxn Mar 04 '21 at 14:48

1 Answers1

1

The problem was I was converting from XML to JSON to Object. I've decided to go from XML to object directly:

  [XmlRoot(ElementName = "Show", Namespace = "http://REDACTED/schema")]
            public class Show
            {
                [XmlAttribute(AttributeName = "show_no")]
                public string Show_no { get; set; }
                [XmlAttribute(AttributeName = "show_datetime")]
                public string Show_datetime { get; set; }
            }
    
            [XmlRoot(ElementName = "Event", Namespace = "http://REDACTED/schema")]
            public class Event
            {
                [XmlElement(ElementName = "Show", Namespace = "http:/REDACTED/schema")]
                public List<Show> Show { get; set; }
                [XmlAttribute(AttributeName = "event_no")]
                public string Event_no { get; set; }
                [XmlAttribute(AttributeName = "name")]
                public string Name { get; set; }

            }
    
            [XmlRoot(ElementName = "Events", Namespace = "http://REDACTED/schema")]
            public class Events
            {
                [XmlElement(ElementName = "Event", Namespace = "http://REDACTED/schema")]
                public List<Event> Event { get; set; }
                [XmlAttribute(AttributeName = "xmlns")]
                public string Xmlns { get; set; }
            }

Then in the code:

XmlSerializer serializer = new XmlSerializer(typeof(Events));
TextReader reader = new StringReader(response.Content);
Events result = (Events)serializer.Deserialize(reader);

Now I am able to see all data properties normally.

crystyxn
  • 1,411
  • 4
  • 27
  • 59