Ваша проблема может быть воспроизведена на следующем, более минимальном примере. Определите следующую модель:
public class JsonApiMessage
{
public JsonElement data { get; set; }
}
Затем попытайтесь десериализовать и повторно сериализовать пустой объект JSON следующим образом:
var payload = JsonSerializer.Deserialize<JsonApiMessage>("{}");
var newJson = JsonSerializer.Serialize(payload, new JsonSerializerOptions { WriteIndented = true });
И вы получите исключение (demo fiddle # 1 здесь ):
System.InvalidOperationException: Operation is not valid due to the current state of the object.
at System.Text.Json.JsonElement.WriteTo(Utf8JsonWriter writer)
at System.Text.Json.Serialization.Converters.JsonConverterJsonElement.Write(Utf8JsonWriter writer, JsonElement value, JsonSerializerOptions options)
Кажется, проблема в том, что JsonElement
представляет собой struct
и значение по умолчанию для этой структуры не может быть сериализовано. Фактически, простое выполнение JsonSerializer.Serialize(new JsonElement());
вызывает то же исключение (демонстрационная скрипка # 2 здесь ). (Это отличается от JObject
, который является ссылочным типом, чье значение по умолчанию, конечно, null
.)
Итак, каковы ваши варианты? Вы можете сделать все свои свойства JsonElement
обнуляемыми и установить IgnoreNullValues = true
при повторной сериализации:
public class JsonApiData
{
[JsonPropertyName("type")]
public string Type { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("attributes")]
public JsonElement? Attributes { get; set; }
[JsonPropertyName("meta")]
public JsonElement? Meta { get; set; }
[JsonPropertyName("relationships")]
public JsonElement? Relationships { get; set; }
}
А затем:
var reserialisedPayload = JsonSerializer.Serialize(payload, new JsonSerializerOptions { IgnoreNullValues = true });
Демо fiddle # 3 здесь .
Или вы можете упростить модель данных, привязав все свойства JSON, отличные от Id
, к свойству JsonExtensionData
например, так:
public class JsonApiData
{
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonExtensionData]
public Dictionary<string, JsonElement> ExtensionData { get; set; }
}
При таком подходе не требуется вручную устанавливать IgnoreNullValues
при повторной сериализации, и, таким образом, ASP. NET Ядро будет правильно правильно сериализовать модель.
Демонстрационная скрипка # 4 здесь .