BotFramework V4:RepromptDialogAsync无法正常工作

问题描述 投票:0回答:1

我不能让RepromptDialogAsync()工作。我是这样做的。当选择对话框b时,它应该重新提示选择提示,因为对话框B还没有准备好。但是当选择对话框b时,它什么都不做。我做错了吗?我在文档上找不到任何RepromptDialogAsync()教程。谢谢!

主要代码:

public class MainDialog : ComponentDialog
{
    private const string InitialId = "mainDialog";
    private const string ChoicePrompt = "choicePrompt";
    private const string DialogAId = "dialogAId";

    public MainDialog(string dialogId)
        : base(dialogId)
    {
        InitialDialogId = InitialId;

        WaterfallStep[] waterfallSteps = new WaterfallStep[]
         {
            FirstStepAsync,
            SecondStepAsync,
            ThirdStepAsync,
            FourthStepAsync
         };
        AddDialog(new WaterfallDialog(InitialId, waterfallSteps));
        AddDialog(new DialogA(DialogAId));
    }

    private static async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
    {
        return await stepContext.PromptAsync(
            ChoicePrompt,
            new PromptOptions
            {
                Prompt = MessageFactory.Text($"Here are your choices:"),
                Choices = new List<Choice>
                    {
                        new Choice
                        {
                            Value = "Open Dialog A",
                        },
                        new Choice
                        {
                            Value = "Open Dialog B",
                        },
                    },
                RetryPrompt = MessageFactory.Text($"Please choose one of the options."),
            });
    }

    private static async Task<DialogTurnResult> SecondStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
    {
        var response = (stepContext.Result as FoundChoice)?.Value.ToLower();

        if (response == "open dialog a")
        {
            return await stepContext.BeginDialogAsync(DialogAId, cancellationToken: cancellationToken);
        }

        if (response == "open dialog b")
        {
            await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Dialog B is not ready need to reprompt previous step."));
            await stepContext.RepromptDialogAsync();
        }

        return await stepContext.NextAsync();
    }

   private static async Task<DialogTurnResult> ThirdStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
    {
       // do something else
        return await stepContext.NextAsync();
    }

    private static async Task<DialogTurnResult> FourthStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
    {
        // what is the best way to end this?
        // return await stepContext.ReplaceDialogAsync(InitialId);
        return await stepContext.EndDialogAsync();
    }
c# botframework
1个回答
0
投票

我将在这个答案中解决几个问题:

回答你的实际问题

RepromptDialogAsync() calls reprompt on the currently active dialog, but is meant to be used with Prompts that have a reprompt behaviorChoicePrompt确实有reprompt选项,但不打算在这种情况下使用。相反,你会调用你的提示,在OnTurnAsync中验证响应,并在必要时调用dc.RepromptDialogAsync()

你的OnTurnAsync可能看起来像这样:

public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
    var activity = turnContext.Activity;

    var dc = await Dialogs.CreateContextAsync(turnContext);

    if (activity.Type == ActivityTypes.Message)
    {
        if (activity.Text.ToLower() == "open dialog b")
        {
            await dc.RepromptDialogAsync();
        };
...

话虽这么说,我根本不会使用RepromptDialogAsync()作为你的用例。而是,使用以下选项之一:

1. ReplaceDialogAsync()

最简单的选择是替换:

await stepContext.RepromptDialogAsync();

有:

return await stepContext.ReplaceDialogAsync(InitialId);

这将启动你的“mainDialog”结束。在你的例子中,这很好,因为你从第二步重新开始到第一步。

2. Prompt Validation

ChoicePrompt会自动验证用户是否使用有效选项进行响应,但您可以传入自己的自定义验证器。就像是:

AddDialog(new ChoicePrompt(choicePrompt, ValidateChoice));
...
private async Task<bool> ValidateChoice(PromptValidatorContext<FoundChoice> promptContext, CancellationToken cancellationToken)
{
    if (promptContext.Recognized.Value.Value.ToLower() == "open dialog b")
    {
        return false;
    }
    else
    {
        return true;
    }
}

Other Issues

但实际上,如果没有准备好,您不应该提示用户选择“对话框b”。相反,你可以这样做:

var choices = new List<Choice>
        {
            new Choice
            {
                Value = "Open Dialog A",
            }
        };
if (bIsReady)
{
    choices.Add(new Choice
    {
        Value = "Open Dialog B",
    });
};
© www.soinside.com 2019 - 2024. All rights reserved.