Запрос Космоса БД Cosmos Сериализует / Десериализует Сбои с NewtonSoft JsonConvert
Я пытаюсь упаковать несколько объектов параметров для отправки в функцию HttpTrigger функций Azure. Часть пакета - это объект RequestOptions, необходимый для действий Cosmos DB. Должно быть очень простым, сериализовать объект и десериализовать на стороне функций. Проблема в том, что JsonConvert не будет сериализовать объект PartitionKey объекта RequestOptions. Класс запечатан. есть идеи как это сделать? Мой код простой тест. Создать объект добавить ключ раздела. Сериализуйте это. Десериализовать его и проверить значение PartitionKey. Это всегда ноль. Я не смог найти ответ на это. Похоже, возможная ошибка в классе RequestOptions, препятствующая сериализации JsonConvert.
public static void Main(string[] args)
{
var partitionKeyValue = "39393939"; // Some partition key in Cosmos DB collection
var requestOptions = new RequestOptions
{
PartitionKey = new PartitionKey(partitionKeyValue)
};
var data = JsonConvert.SerializeObject(requestOptions);
// send data to Azure Functions
var requestOptions1 = JsonConvert.DeserializeObject<RequestOptions>(data);
}
Я использую VS отладчик для проверки значений. Я знаю, что могу использовать PartitionKey, потому что я могу кодировать его непосредственно в функции функций Azure, и код работает. Таким образом, проблема заключается в сериализации, производящей NULL для ключа раздела. Если это не может быть сериализовано, какой смысл?
1 ответ
PartitionKey
Класс не предоставляет никаких открытых членов, которые Json.Net сможет "увидеть" для сериализации в JSON. Поэтому, когда вы пытаетесь сериализовать его напрямую, он появляется как пустой объект {}
в JSON. При десериализации Json.Net пытается использовать PartitionKey
конструктор, но не знает, что заполнить для keyValue
параметр, поэтому он просто использует null
, Так что это объясняет результат, который вы видите.
Я заметил, что PartitionKey
Кажется, что у самого класса есть поддерживаемый способ конвертировать его в JSON и обратно, используя его ToString()
а также FromJsonString()
методы. Так что если вы хотите включить этот класс в большую сериализацию, вы можете сделать простой JsonConverter
это позволило бы ему работать:
public class PartitionKeyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(PartitionKey);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
string s = (string)reader.Value;
return s != null ? PartitionKey.FromJsonString(s) : null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString());
}
}
Чтобы использовать конвертер, просто передайте экземпляр SerializeObject
а также DeserializeObject<T>
методы как это:
var data = JsonConvert.SerializeObject(requestOptions, new PartitionKeyConverter());
var requestOptions1 = JsonConvert.DeserializeObject<RequestOptions>(data, new PartitionKeyConverter());
Скрипка: https://dotnetfiddle.net/Jqo7mg