C# BOTFramew4:RepromptDialogAsync不工作

C# BOTFramew4:RepromptDialogAsync不工作,c#,botframework,C#,Botframework,我无法使RepromptDialogAsync()正常工作。我是这样做的。选择dialogb时,应重新提示选择提示,因为dialogb尚未就绪。但是当选择dialogb时,它什么也不做。我做错了吗?我找不到任何有关文档的RepromptDialogAsync()教程。谢谢大家! 主要代码: public class MainDialog : ComponentDialog { private const string InitialId = "mainDialog"; priva

我无法使
RepromptDialogAsync()
正常工作。我是这样做的。选择dialog
b
时,应重新提示选择提示,因为dialog
b
尚未就绪。但是当选择dialog
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();
    }
公共类MainDialog:ComponentDialog { private const string InitialId=“mainDialog”; private const string ChoicePrompt=“ChoicePrompt”; 私有常量字符串DialogAId=“DialogAId”; 公共主对话框(字符串对话框ID) :base(dialogId) { InitialDialogId=InitialId; waterwallstep[]waterwallsteps=新的waterwallstep[] { FirstStepAsync, 第二步异步, 第三步同步, 第四步异步 }; AddDialog(新的WaterWallDialog(初始ID,WaterWallSteps)); AddDialog(新建DialogA(DialogAId)); } 专用静态异步任务FirstStepAsync(WaterCallStepContext stepContext,CancellationToken CancellationToken=default(CancellationToken)) { return wait stepContext.PromptAsync( 选秀节目主持人, 新提示 { Prompt=MessageFactory.Text($“这是您的选择:”), 选项=新列表 { 新选择 { Value=“打开对话框A”, }, 新选择 { Value=“打开对话框B”, }, }, RetryPrompt=MessageFactory.Text($“请选择一个选项。”), }); } 专用静态异步任务SecondStepAsync(WaterCallStepContext stepContext,CancellationToken CancellationToken=default(CancellationToken)) { var response=(stepContext.Result as FoundChoice)?.Value.ToLower(); 如果(响应=“打开对话框a”) { return wait-stepContext.BeginDialogAsync(DialogAId,cancellationToken:cancellationToken); } 如果(响应=“打开对话框b”) { 等待stepContext.Context.SendActivityAsync(MessageFactory.Text($“对话框B未准备好,需要重新启动上一步”); 等待stepContext.RepromptDialogAsync(); } 返回wait-stepContext.NextAsync(); } 专用静态异步任务第三步同步(WaterWallStepContext stepContext,CancellationToken CancellationToken=default(CancellationToken)) { //做点别的 返回wait-stepContext.NextAsync(); } 专用静态异步任务FourthStepAsync(WaterWallStepContext stepContext,CancellationToken CancellationToken=default(CancellationToken)) { //结束这一切的最好办法是什么? //返回wait-stepContext.ReplaceDialogAsync(InitialId); 返回wait-stepContext.EndDialogAsync(); }
我将在这个答案中解决几个问题:

回答你的实际问题
RepromptDialogAsync()
ChoicePrompt
确实有一个
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()
最简单的选择是替换:

wait stepContext.RepromptDialogAsync();

与:

返回等待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;
    }
}
var choices = new List<Choice>
        {
            new Choice
            {
                Value = "Open Dialog A",
            }
        };
if (bIsReady)
{
    choices.Add(new Choice
    {
        Value = "Open Dialog B",
    });
};
AddDialog(新建ChoicePrompt(ChoicePrompt,validateechoice));
...
专用异步任务ValidateChoice(PromptValidatorContext promptContext,CancellationToken CancellationToken)
{
if(promptContext.Recognized.Value.Value.ToLower()=“打开对话框b”)
{
返回false;
}
其他的
{
返回true;
}
}
其他问题 实际上,如果对话框b未准备好,您不应该提示用户选择“对话框b”。相反,您可以执行以下操作:

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;
    }
}
var choices = new List<Choice>
        {
            new Choice
            {
                Value = "Open Dialog A",
            }
        };
if (bIsReady)
{
    choices.Add(new Choice
    {
        Value = "Open Dialog B",
    });
};
var选项=新列表
{
新选择
{
Value=“打开对话框A”,
}
};
如果(准备就绪)
{
选项。添加(新选项)
{
Value=“打开对话框B”,
});
};

“谢谢你,先生,我想让你知道,如果它没有准备好,那是因为我想让用户知道这个特性在将来是可用的。重新启动对话有点恼人,因为在我的真实对话中,提示在对话的中间,所以重新启动它有很长的路要走。再次提示。验证程序不会返回我想要的选项。我不知道如何在
OnTurnAsync
中的其他类中验证我的提示。先生,您能教我怎么做吗?“相反,您需要调用提示,在OnTurnAsync中验证响应,并根据需要调用dc.RepromptDialogAsync()什么意思,“验证程序不通过返回选项”?我已经编辑了我的答案,将
OnTurnAsync
的代码包括在内,尽管我真的建议使用提示验证(在我的答案中为2)。谢谢你,先生。我想我会坚持你的答案