Cosmos DB RequestOptions使用NewtonSoft JsonConvert序列化/反序列化失败



我正在尝试打包许多参数对象,以发送到Azure函数HttpTrigger函数。包的一部分是Cosmos DB操作所必需的RequestOptions对象。应该非常简单,序列化对象并在函数端反序列化。问题是JsonConvert不会序列化RequestOptions对象的PartitionKey对象。该类已封存。知道怎么做吗?我的代码是一个简单的测试。创建一个对象并添加分区键。序列化它。反序列化它并检查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的序列化中。如果不能序列化,那又有什么意义呢?

PartitionKey类不公开Json.Net能够"看到"的任何公共成员,以便序列化到Json中。因此,当您尝试直接序列化它时,它在JSON中显示为一个空对象{}。在反序列化时,Json.Net尝试使用PartitionKey构造函数,但不知道该为keyValue参数填充什么,所以它只使用null。这就解释了你所看到的结果。

我注意到PartitionKey类本身似乎有一种受支持的方法,可以通过使用其ToString()FromJsonString()方法将其转换为JSON和从JSON转换过来。因此,如果你想将这个类合并到一个更大的序列化中,你可以制作一个简单的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());
}
}

要使用转换器,只需将一个实例传递给SerializeObjectDeserializeObject<T>方法,如下所示:

var data = JsonConvert.SerializeObject(requestOptions, new PartitionKeyConverter());
var requestOptions1 = JsonConvert.DeserializeObject<RequestOptions>(data, new PartitionKeyConverter());

Fiddle:https://dotnetfiddle.net/Jqo7mg

相关内容

  • 没有找到相关文章

最新更新