我正在尝试打包许多参数对象以发送给Azure Functions 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 Functions函数中对其进行编码,并且代码可以正常工作。因此,问题在于序列化会为分区键生成NULL。如果无法序列化,那有什么意义?
答案 0 :(得分:3)
PartitionKey
类未公开Json.Net能够“看到”以序列化为JSON的任何公共成员。因此,当您尝试直接对其进行序列化时,它会在JSON中作为空对象{}
出现。在反序列化方面,Json.Net尝试使用PartitionKey
构造函数,但不知道为keyValue
参数填写什么,因此它仅使用null
。这样可以解释您所看到的结果。
我注意到PartitionKey
类本身似乎具有受支持的方法,可以使用其ToString()
和FromJsonString()
方法将其与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());
}
}
要使用转换器,只需将实例传递给SerializeObject
和DeserializeObject<T>
方法,如下所示:
var data = JsonConvert.SerializeObject(requestOptions, new PartitionKeyConverter());
var requestOptions1 = JsonConvert.DeserializeObject<RequestOptions>(data, new PartitionKeyConverter());