如果用户想停止则退出当前对话框

Quit current dialog if user wants to stop

我正在使用多个对话框。有些使用 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);
        }
    }

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

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

在我的 MessageController 中的这一行:

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

现在我不确定找不到什么密钥,也不确定为什么它会向我发送这个。感谢您的帮助!

一般来说,当有人想要完成类似这样的事情(例如取消关键字)时,他们会使用 scorables. Scorables are global message handlers so if a keyword you set triggers one it gets handled before firing off your normal dialog flow. There are some great resources out there for scorables like this blog or this video 来帮助您入门。

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