2

我正在使用多个对话框。有些使用 formbuilder,有些使用 ResultAfter 方法来自定义提示值。我想要一种方法来检查退出词(如停止、退出等)的传入消息。

我认为 StartAsync 函数将是一个好的开始。看到所有对话框都是从我的 RootDialog 转发的,我在 RootDialog 中实现了这个:

    public override async Task StartAsync(IDialogContext context)
    {
        string[] stopStrings = { "quit", "cancel", "exit" };
        var msg = context.Activity.AsMessageActivity().Text;
        if (stopStrings.Any(msg.Contains))
        {
            await context.PostAsync("You cancelled.");
            context.Done(true);
        }
        else
        {
            context.Wait(this.MessageReceived);
        }
    }

当我要求机器人“停止”时,它成功地告诉我我取消了。但是在我发送的下一条消息中,我收到了这个错误:

Exception thrown: 'System.Collections.Generic.KeyNotFoundException'

在我的 MessageController 中的这一行:

await Conversation.SendAsync(activity, () => new RootDialog());

现在我不确定没有找到什么密钥,以及为什么它会向我发送这个。帮助表示赞赏!

4

1 回答 1

1

通常,当有人想要完成类似这样的事情时,例如取消关键字时,他们会使用scorables。Scorables 是全局消息处理程序,因此如果您设置的关键字触发了一个关键字,它将在触发您的正常对话流之前得到处理。有一些很棒的资源可以用于评分,比如这个博客这个视频应该让你开始。

我实际上无法重现此错误,但这里有一些提示和想法。我想我从来没有见过有人把逻辑放进去StartAsync并按照他们的期望行事。当我尝试你的代码时,我无法弄清楚为什么你会以你的方式覆盖它。逻辑应该在MessageReceivedAsync. 尝试将您的逻辑移入MessageReceivedAsync方法中。如果您绝对想这样做,可以尝试另一件事,context.Wait(this.MessageReceivedAsync);因为您RootDialog无论如何都在替换 context.Done(true) ,消息只会从消息控制器路由到那里,您不需要手动操作对话框堆栈,虽然我不知道你的项目的结构,所以我可能是错的。

于 2018-05-09T18:11:53.360 回答