使用带有自定义序列化程序的 CosmosClient 查询 CosmosDb

问题描述 投票:0回答:1

我正在尝试使用 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

问候。

c# azure-functions json.net azure-cosmosdb
1个回答
0
投票

这是一件不常见的事情,但在这种情况下,您必须处置流。这就是错误消息试图告诉您的内容。

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

© www.soinside.com 2019 - 2024. All rights reserved.