如何通过 Microsoft Bot Framework 将记录插入到 Azure Table 存储?

How to insert records to Azure Table Storage via Microsoft Bot Framework?

目前我正在使用 C# 使用 Bot Framework 4.0,我正在尝试 实现一个解决方案,我将来自用户的消息存储在 Azure Table 存储中。 我已经想出了一个实现这个目标的想法,但我的方法只适用于本地 当我通过 Bot Framework Emulator 测试它时。

当我将我的机器人代码发布到 Azure 时,消息不会存储在 Table 存储中。 我有点困惑,因为我真的不知道为什么会这样。我已经检查了 App Insights,但显示的信息对我帮助不大。

这些是我安装的 Nugget-Packages:

还有我安装的 SDK:

我的整个实现由四个要素组成,现在我将简要解释一下:

        private static CloudTable GetTableReference()
        {
            var storageAccount = CloudStorageAccount.Parse("<connection-string>");
            var tableClient = storageAccount.CreateCloudTableClient();

            return tableClient.GetTableReference("<table-name>");
        }

第一种方法是打包 Azure Table 存储的凭据。该术语是一个占位符,代表 Azure Table 存储的连接字符串。这是 table 存储名称的占位符(很明显)。

private static void InsertRecord(ITurnContext<IMessageActivity> turnContext, CloudTable table)
        {
            string partitionKey = DateTime.Now.ToString();
            string rowKey = DateTime.Now.ToString();

            var Eintrag = new UserEntity(partitionKey, rowKey)
            {
                UserStatement = $"{turnContext.Activity.Text}",
            };

            var insertOperation = TableOperation.Insert(Eintrag);
            table.ExecuteAsync(insertOperation);
        }

第二种方法为Table存储准备内容。例如,用户的消息也存储在“UserStatement”变量中,还有一个时间戳。

protected async Task NoMatchFound(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var table = GetTableReference();
            InsertRecord(turnContext, table);

            // Wird ausgeführt, wenn keine KnowledgeBase gefunden wird
            System.Diagnostics.Debug.WriteLine("### FINDE KEINE PASSENDE ANTWORT ###");
            await turnContext.SendActivityAsync(MessageFactory.Text("Leider kann ich Ihnen hierbei noch nicht weiterhelfen. Ich bin aber schon dabei, Neues zu lernen!"), cancellationToken);
        }

在最后一个方法中,所有内容都放在一起并最终执行。这三个提到的方法在同一个名为“Dispatchbot.cs”的文件中(我为我的机器人使用了 Microsoft 的 NLP with Dispatch 示例)。

using Microsoft.Azure.Cosmos.Table;
using System;

namespace TableStorage
{
    public class UserEntity : TableEntity
    {
        public UserEntity(string partitionKey, string rowKey)
        {
            PartitionKey = partitionKey;
            RowKey = rowKey;
        }

        public UserEntity()
        {
        }

        public string UserStatement { get; set; }

    }
}

我最后得到的是另一个名为“UserEntity.cs”的文件,其中打包了 table 条目的内容。整个实现肯定更容易实现。

我唯一需要做的就是调用 NoMatchFound() 方法,用户的输入应该存储在 Azure Table 存储中。但如果我尝试在线测试,情况就不是这样了。

这是一个视频,其中我展示了 Table 存储记录在本地没有任何问题:https://youtu.be/fFtzjmOfQDs

我还会附上我的应用见解的屏幕截图 - 也许这有帮助。

希望你能帮帮我!如果我需要添加更多信息,请随时提出要求。

我看了你提供的视频,发现在你的本地机器上,datetime是这样的格式:18.01.2021 17:35:59.

所以我认为根本原因是当它部署到 azure 时,datetime 是这种格式:1/19/2021 10:09:31 AM。根据此文档 Characters Disallowed in Key Fields,字符 / 不允许用于 PartitionKeyRowKey 属性。

所以在方法private static void InsertRecord(xxx)中,请使用Replace方法将字符/替换为字符.或其他允许的字符。如下所示:

    private static void InsertRecord(ITurnContext<IMessageActivity> turnContext, CloudTable table)
    {

        //replace the character / with character .
        string partitionKey = DateTime.Now.ToString().Replace('/','.');
        string rowKey = DateTime.Now.ToString().Replace('/','.');

        var Eintrag = new UserEntity(partitionKey, rowKey)
        {
            UserStatement = $"{turnContext.Activity.Text}",
        };

        var insertOperation = TableOperation.Insert(Eintrag);
        table.ExecuteAsync(insertOperation);
    }