【问题标题】:Cosmos DB RequestOptions Serialize/Deserialize Fails with NewtonSoft JsonConvertCosmos DB RequestOptions Serialize/Deserialize 使用 NewtonSoft JsonConvert 失败
【发布时间】:2019-06-07 15:10:24
【问题描述】:

我正在尝试打包一些参数对象以发送到 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 的序列化中。如果不能序列化,那有什么意义呢?

【问题讨论】:

    标签: json json.net azure-cosmosdb jsonconvert


    【解决方案1】:

    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());
        }
    }
    

    要使用转换器,只需将实例传递给SerializeObjectDeserializeObject&lt;T&gt; 方法,如下所示:

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

    小提琴:https://dotnetfiddle.net/Jqo7mg

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多