我正在尝试使用 CosmosClient 和 Azure Function 内的自定义序列化程序来查询 CosmosDB。
这是我的自定义序列化器:
public class CosmosDbSerializerService : CosmosSerializer
{
private readonly JsonSerializer jsonSerializer;
public CosmosDbSerializerService()
{
jsonSerializer = JsonSerializer
.Create(JsonSerializerFactory.GetJsonSerializerSettings());
}
public override T FromStream<T>(Stream stream)
{
using (StreamReader streamReader = new(stream))
using (JsonTextReader jsonTextReader = new(streamReader))
{
return jsonSerializer
.Deserialize<T>(jsonTextReader);
}
}
public override Stream ToStream<T>(T input)
{
using (StringWriter stringWriter = new())
using (JsonTextWriter jsonTextWriter = new(stringWriter))
{
jsonSerializer.Serialize(jsonTextWriter, input, input.GetType());
return new MemoryStream(Encoding.UTF8.GetBytes(stringWriter.ToString()));
}
}
}
这是我使用 DI 设置
CosmosClient
的代码:
builder.Register(_ =>
{
CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder(productionDatabaseSettings.ConnectionString)
.WithCustomSerializer(new CosmosDbSerializerService())
.WithHttpClientFactory(() =>
{
HttpMessageHandler httpMessageHandler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
return new HttpClient(httpMessageHandler);
})
.WithConnectionModeGateway();
return cosmosClientBuilder.Build();
});
如果我运行代码并使用 Postman 调用该函数,我会得到 200 OK,但不会返回任何结果。我使用在线工具 Data Explorer 检查了查询字符串,它按预期工作。
我注意到,但我无法解释为什么,如果我按照 Visual Studio 中运行的代码,执行
CosmosDbSerializerService.FromStream
后,执行会跳转到 Microsoft 实现的对象 CosmosJsonSerializerWrapper
(这里)进入方法:
public override T FromStream<T>(Stream stream)
{
T item = this.InternalJsonSerializer.FromStream<T>(stream);
if (stream.CanRead)
{
throw new InvalidOperationException("Json Serializer left an open stream.");
}
return item;
}
抛出异常。
不知道如何解决它,还有一个问题:为什么,如果我设置了
CosmosSerializer
,代码仍然使用CosmosJsonSerializerWrapper
?
问候。
这是一件不常见的事情,但在这种情况下,您必须处置流。这就是错误消息试图告诉您的内容。
public override T FromStream<T>(Stream stream)
{
// Microsoft.Azure.Cosmos.Client requires JsonSerializer to close the stream.
using (stream) //<--- here
using (StreamReader streamReader = new(stream))
using (JsonTextReader jsonTextReader = new(streamReader))
{
return jsonSerializer
.Deserialize<T>(jsonTextReader);
}
}
或者您也可以致电
Dispose()