带有 Cosmos DB 绑定的 Azure 函数返回格式化的 DateTime?

Posted

技术标签:

【中文标题】带有 Cosmos DB 绑定的 Azure 函数返回格式化的 DateTime?【英文标题】:Azure Function with Cosmos DB binding returning formatted DateTime? 【发布时间】:2020-06-04 13:35:13 【问题描述】:

在 CosmosDB 中存储作为字符串给出的 DateTime 对象时遇到了一些困难。为了确保它与 DateTime 对象的序列化无关,我目前正在使用 strings only

我在数据库中存储的文档如下所示:


    "available": true,
    "id": "391a802c-ac42-443b-860a-8ab7061b389c",
    "checked_date": "2020-06-04T12:53:29.4625341Z",
    "code": "AAAA",
    "_rid": "w6VGAOSKaJABAAAAAAAAAA==",
    "_self": "dbs/w6VGAA==/colls/w6VGAOSKaJA=/docs/w6VGAOSKaJABAAAAAAAAAA==/",
    "_etag": "\"00000000-0000-0000-3a70-96abc3ea01d6\"",
    "_attachments": "attachments/",
    "_ts": 1591275829

我正在使用一个非常简单的函数来查询它:

[FunctionName("GetObject")]
public static async Task<IActionResult> GetObject(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "object/code")] HttpRequest req,
    [CosmosDB(
        databaseName: "database01",
        collectionName: "objecttable",
        ConnectionStringSetting = "CosmosDBString",
        SqlQuery = "SELECT c.id, c.code, c.available, c.checked_date FROM objecttable c WHERE LOWER(c.code)=LOWER(code)")] IEnumerable<ObjectEntity> entities,
                ILogger log)

    log.LogInformation("GetObject function processed a request.");
    return new JsonResult(entities);

ObjectEntity 类如下所示:

[JsonObject(MemberSerialization.OptIn)]
public class ObjectEntity

    [JsonProperty(PropertyName = "available")]
    public bool Available get; set;

    [JsonProperty(PropertyName = "id")]
    public string Id get; set;

    [JsonProperty(PropertyName = "checked_date")]
    public string CheckedDate get; set;

    [JsonProperty(PropertyName = "code")]
    public string Codeget; set;

当在“checked_date”字段中存储一些任意字符串数据时,字符串会按预期返回。当我存储像“2020-06-04T12:53:29.4625341Z”这样的字符串时,我得到的是“06/04/2020 12:53:29”,而不是应用任何反序列化、类型转换或类似的东西。

使用 CosmosDB Explorer,我看到了正确的字符串表示。

这与Azure函数的返回对象无关,问题已经出现在函数内部。如果我在函数中设置断点,我可以看到实体对象中的字符串已经搞砸了。

我在这里做错了什么? CosmosDB 绑定是否在这里弄乱了我的字符串?


更新: 我已将 CosmosDB 连接模式设置为“直接”并使用 Fiddler 跟踪请求。看来 CosmosDB 确实在响应正文中返回了正确的字符串:

"_rid":"w6VGAOSKaJA=","Documents":["id":"391a802c-ac42-443b-860a-8ab7061b389c","code":"AAAA","available":true,"checked_date":"2020-06-04T12:53:29.4625341Z"],"_count":1

所以问题必须与绑定本身或反序列化有关?

【问题讨论】:

【参考方案1】:

这可能与使用默认 Newtonsoft.Json 序列化程序设置的 SDK 有关,该设置将字符串解析为日期时间(https://github.com/Azure/azure-cosmos-dotnet-v2/issues/235 和 https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_DateParseHandling.htm),DateParseHandling.None 可以解决它。

遗憾的是,绑定不允许您定义 DocumentClient 的初始化方式。一种替代方法是维护您自己的实例而不是使用绑定(我猜这最终是更多的代码)。 DocumentClient 有一个构造函数,可让您指定 JsonSerializerSettings 的实例。

确保实例是在Functions' guidelines 之后创建的。

另一种选择是全局设置,但这会影响使用 Newtonsoft.Json 的所有其他代码:Json.net global settings

最后,您可以在仅按原样输出文本的属性上创建一个自定义转换器。

【讨论】:

谢谢!按照您的提示,我发现了以下错误报告:github.com/JamesNK/Newtonsoft.Json/issues/862 该行为是由 Json.Net 设计的,因此我绝对需要指定我自己的序列化设置,这会导致使用绑定创建的 DocumentClient 以外的 DocumentClient。跨度>

以上是关于带有 Cosmos DB 绑定的 Azure 函数返回格式化的 DateTime?的主要内容,如果未能解决你的问题,请参考以下文章

Azure Cosmos DB:使用 UpsertDocumentAsync 违反唯一索引约束

Cosmos DB 更改源触发 Azure 函数:租赁丢失异常

如何在 Python 中从 Azure 函数调用 Cosmos DB 存储过程?

在本地使用 Cosmos DB 运行 Azure Functions - 找不到 CosmosDBAttribute.ConnectionStringSetting

Azure C#,过滤存储在cosmos DB中的原始数据(通过功能URL显示)

sql Azure Cosmos DB