BotFramework V4:RepromptDialogAsync不起作用

时间:2019-02-24 08:04:11

标签: c# botframework

我无法让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();
    }

1 个答案:

答案 0 :(得分: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。即时验证

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;
    }
}

其他问题

但是,实际上,如果尚未准备好,则不应提示用户选择“对话框b”。相反,您可以执行以下操作:

var choices = new List<Choice>
        {
            new Choice
            {
                Value = "Open Dialog A",
            }
        };
if (bIsReady)
{
    choices.Add(new Choice
    {
        Value = "Open Dialog B",
    });
};