场景:
- 我有一个cosmosDb容器存储在Azure中。
- 我有这样的数据类,我可以读写:
public class MyClass {
public Guid Id { get; private set; }
public string PartitionKey { get; private set; }
[JsonConverter(typeof(MyTypeJsonConverter))]
//[Newtonsoft.Json.JsonConverter(typeof(MyTypeNewtonsoftJsonConverter))]
public MyType Custom { get; private set; }
[JsonConstructor] // <-- I've tried with and without this
public MyClass(Guid id, string pk, MyType custom) {
Custom = custom; Id = id; PartitionKey = pk;
}
}
- 正如你所看到的,有一个自定义类型MyType,它被自定义转换器转换。
- 为了测试目的,我用Newtonsoft和System编写了转换器。文本:
public class MyTypeJsonConverter : JsonConverter<MyType> {
public override bool CanConvert(Type objectType) { ... }
public override void Write(...) { ... }
public override Context Read(...) { ... }
}
public class ContextNewtonsoftJsonConverter : Newtonsoft.Json.JsonConverter {
...
}
- 我知道MyType工作,转换器工作,因为当我这样做的时候,序列化和反序列化都与System.Text.Json和Newtonsoft.Json一样工作:
Newtonsoft
//var myClass = JsonConvert.DeserializeObject<MyClass>(someJson);
//System.Text.Json
var myClass2 =
JsonSerializer.Deserialize<MyClass>(someJson,
new JsonSerializerOptions()
{ IgnoreNullValues = false, PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
- 当我从CosmosDb读取和写入对象时,也会发生类似的反序列化。
CosmosClientOptions options = new()
{
ConnectionMode = DebugHelper.DebugMode ?
ConnectionMode.Gateway : ConnectionMode.Direct,
SerializerOptions = new CosmosSerializationOptions
{
IgnoreNullValues = false,
PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
},
};
var cosmosClient = CosmosClient
.CreateAndInitializeAsync(connectionString,
containersList, options)
.GetAwaiter()
.GetResult();
var container = cosmosClient .GetContainer("mydatabase", "mycontainer");
var items = container.GetItemLinqQueryable<MyType>(allowSynchronousQueryExecution: true);
foreach (var item in items)
{
await container.DeleteItemAsync<MyType>(item.Id.ToString(), new PartitionKey(item.PartitionKey));
}
问题:
上面的代码与NewtonSoft版本完美配合......但System.Text.Json版本失败。
---- Newtonsoft.Json.JsonSerializationException:将值“my string value”转换为类型“MyType”时出错。--------- System.ArgumentException:无法从System.String强制转换或转换为MyType。
该异常不会在转换器的Read
和Write
函数内**发生。这是“事先”发生的。这就像[JsonConverter(...)]
属性被JsonSerializer.Deserialize<Mytype>
理解,而不是cosmosContainer.DoSomethingWithItem<MyType>
。
**同样;它与普通的序列化/反序列化一起工作,**当我使用Newtonsoft时,它与CosmosClient一起工作。
问题:
- (在你深入到复杂的Json之前)你能发现一个明显的错误吗?
- 我是否需要注册自定义JsonConverter,如果是的话,最简洁的方式是什么?(任何不需要我实现一个完整的自定义序列化器**传递给CosmosDb的东西...除非你能向我证明,有一个很好的解释为什么Newtonsoft可以不使用它而System.Text.Json不能)
1条答案
按热度按时间ztyzrc3y1#
是的,您可以(在您的情况下,也应该)注册一个自定义序列化器:
完整示例here