Выйти из текущего диалога, если пользователь хочет остановить - PullRequest
0 голосов
/ 09 мая 2018

Я использую несколько диалогов.Некоторые используют 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());

Теперь я не уверен, какой ключ не найден и почемуэто посылает мне это.Помощь приветствуется!

1 Ответ

0 голосов
/ 09 мая 2018

Обычно, когда кто-то хочет выполнить что-то подобное, например, ключевое слово для отмены, он использует scorables . Scorables - это глобальные обработчики сообщений, поэтому, если ключевое слово, которое вы устанавливаете, вызывает его, оно обрабатывается перед тем, как запустить обычный диалог. Есть несколько отличных ресурсов для таких предметов, как этот блог или это видео , которое поможет вам начать.

Я не смог воспроизвести эту ошибку, но вот несколько советов и мыслей. Я не думаю, что когда-либо видел, чтобы кто-то вводил логику в StartAsync и действовал так, как он того ожидал. Я не смог понять, почему вы переопределяете это так, как вы, когда я пробовал ваш код. Логика должна быть в MessageReceivedAsync. Попробуйте перенести свою логику в метод MessageReceivedAsync. Еще одна вещь, которую нужно попробовать, если вы абсолютно хотите сделать это таким образом, чтобы заменить context.Done (true) просто context.Wait(this.MessageReceivedAsync);, поскольку вы все равно находитесь в RootDialog, сообщения будут просто направляться туда от контроллера сообщений, и вы делаете не нужно вручную манипулировать стеком диалогов, хотя я не знаю структуру вашего проекта, поэтому могу ошибаться.

...