I can't seem to solve this one. All other questions i can find with the same issue are for Newtonsoft.Json.
I use an external provided json API which returns a dictionary. But if it's empty, they return an empty array:
With data:
"booking/index": {
"key": {
data...
}
}
Without data:
"booking/index": []
So the System.json deserializer fails with this error (which is understandable):
System.Text.Json.JsonException: The JSON value could not be converted to System.Collections.Generic.Dictionary`2[System.String,checkfront_reports.Models.Api.BookingIndexIndexObj]. Path: $['booking/index'] | LineNumber: 0 | BytePositionInLine: 408.
For reference here is the call i make and the data model:
var bookingIndex = await httpClient.GetFromJsonAsync<BookingIndexObj>($"booking/index?start_date={startDate.ToString("yyyy-MM-dd")}&end_date={endDate.ToString("yyyy-MM-dd")}");
public class BookingIndexObj
{
public BookingRequestObj Request { get; set; }
[JsonPropertyName("booking/index")]
public Dictionary<string, BookingIndexIndexObj> BookingIndex { get; set; }
}
public class BookingIndexIndexObj
{
public string? Code { get; set; }
[JsonPropertyName("status_id")]
public string? StatusId { get; set; }
}
public class BookingRequestObj
{
public int Page { get; set; }
public int Pages { get; set; }
}
I am not sure at all if this is how we are supposed to do this, but at least it worked:
(Note that I simplified the example)
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var emptyJson =
"""
{
"values": []
}
""";
var nonEmptyJson =
"""
{
"values": {
"key1": "value1",
"key2": "value2"
}
}
""";
var emptyResult = JsonSerializer.Deserialize<Model>(emptyJson);
var nonEmptyResult = JsonSerializer.Deserialize<Model>(nonEmptyJson);
emptyResult.Dump();
nonEmptyResult.Dump();
}
}
public class Model
{
[JsonPropertyName("values")]
[JsonConverter(typeof(MySpecialConverter))]
public Dictionary<string,string> Values {get;set;} = new();
}
public class MySpecialConverter : JsonConverter<Dictionary<string,string>>
{
// Omitted writer for brevity.
public override void Write(Utf8JsonWriter writer,
Dictionary<string,string> dictionaryValue,
JsonSerializerOptions options) => throw new NotSupportedException();
public override Dictionary<string,string> Read(ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
// Check for '"booking/index": []' - case:
if (reader.TokenType == JsonTokenType.StartArray)
{
reader.Read();
return new Dictionary<string,string>();
}
// Otherwise pass-through to default converter.
var converter = (JsonConverter<Dictionary<string,string>>)options.GetConverter(typeof(Dictionary<string,string>));
return converter.Read(ref reader, typeToConvert, options);
}
}
=> Fiddle: https://dotnetfiddle.net/J6NbVE
For your reference:
I based this upon this article: How to write custom converters for JSON serialization (marshalling) in .NET