我无法让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();
}
答案 0 :(得分:0)
我将在此答案中解决几个问题:
RepromptDialogAsync()
calls reprompt
on the currently active dialog, but is meant to be used with Prompts that have a reprompt
behavior。 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()
。而是使用以下选项之一:
ReplaceDialogAsync()
最简单的选择是替换:
await stepContext.RepromptDialogAsync();
具有:
return await stepContext.ReplaceDialogAsync(InitialId);
这将重新启动您的“ mainDialog”。在您的示例中,这很好,因为您是从第二步重新回到第一步。
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",
});
};