I am trying to consume an external web service and I am using .NET Core and the Flurl framework. I get a response from the service like below:
[
"Successful Request: 96 Results",
[
{
"eventdate":"2019-10-18",
"name":"",
"url":"",
"info":"",
"showtime":null,
"url_tix":"",
"event_owner":"xxx",
"follow_url":"xxx",
"event_image":"xxx",
"venue":"xxx",
"city":"xxx",
"country":"xxx",
"state":""
}
]
]
and I have a C# entity definition like below:
public class ServiceResponce
{
public Event[] Events { get; set; }
}
public class Event
{
[JsonProperty("eventdate")]
public DateTimeOffset Eventdate { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("info")]
public string Info { get; set; }
[JsonProperty("showtime")]
public object Showtime { get; set; }
[JsonProperty("url_tix")]
public object UrlTix { get; set; }
[JsonProperty("event_owner")]
public string EventOwner { get; set; }
[JsonProperty("follow_url")]
public Uri FollowUrl { get; set; }
[JsonProperty("event_image")]
public object EventImage { get; set; }
[JsonProperty("venue")]
public string Venue { get; set; }
[JsonProperty("city")]
public string City { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("state")]
public string State { get; set; }
}
When I tried to call the Flurl method to consume the web service like below:
var result = await serviceUrl.GetJsonAsync<ServiceResponce>();
I got the error mentioned below:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'xxx.ServiceResponce' 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 '', line 1, position 1.
Do you have any solution for that? Any help always is welcome.
The problem here is the JSON response is actually an array of mixed types. The first element of the array is a string, and the second element is an array of event objects. You will need a custom JsonConverter
to deserialize this JSON.
Here is the code you would need for the converter:
class ServiceResponceConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(ServiceResponce));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JArray ja = JArray.Load(reader);
ServiceResponce resp = new ServiceResponce();
resp.Events = ja[1].ToObject<Event[]>(serializer);
return resp;
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Then, add a [JsonConverter]
attribute to the ServiceResponce
class to tie it to the converter:
[JsonConverter(typeof(ServiceResponceConverter))]
public class ServiceResponce
{
public Event[] Events { get; set; }
}
Now you can deserialize to the ServiceResponce
class as normal and it will work properly.
Optional: If you also want to capture the "Successful Request: 96 Results"
string from the response, add
public string ResultString { get; set; }
to the ServiceResponce
class and add the following line to the the ReadJson
method of the converter:
resp.ResultString = (string)ja[0];
Working demo here: https://dotnetfiddle.net/opPUmX