问题描述
我无法使RepromptDialogAsync()
正常工作.我是这样做的.选择对话框b
时,应重新提示选择提示,因为对话框B
尚未准备好.但是,选择对话框它什么都不做的时候.我做错了吗?我在文档上找不到任何RepromptDialogAsync()
教程.谢谢!
I can't make RepromptDialogAsync()
to work. I am doing it like this. When dialog b
is chosen it should re-prompt the choice prompt because dialog B
is not yet ready. But when choosing dialog b
it is doing nothing. Am I doing it wrong? I can't find any RepromptDialogAsync()
tutorial on docs. Thank you!
主要代码:
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();
}
推荐答案
我将在此答案中解决几个问题:
I'll address a couple of issues in this answer:
RepromptDialogAsync()
在当前活动的对话框上调用reprompt
,但应与具有reprompt
行为的提示一起使用. ChoicePrompt
确实具有reprompt
选项,但并不打算在此上下文中使用.取而代之的是,您将调用提示符,在OnTurnAsync
中验证响应,然后根据需要调用dc.RepromptDialogAsync()
.
RepromptDialogAsync()
calls reprompt
on the currently active dialog, but is meant to be used with Prompts that have a reprompt
behavior. ChoicePrompt
does have a reprompt
option, but isn't meant to be used in this context. Instead, you'd call your prompt, validate the response within OnTurnAsync
, and call dc.RepromptDialogAsync()
as necessary.
您的OnTurnAsync
可能看起来像这样:
Your OnTurnAsync
might look something like this:
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()
用于您的用例.而是使用以下选项之一:
That being said, I wouldn't use RepromptDialogAsync()
for your use case, at all. Instead, use one of the following options:
最简单的选择是替换:
await stepContext.RepromptDialogAsync();
具有:
return await stepContext.ReplaceDialogAsync(InitialId);
这将重新启动您的"mainDialog".在您的示例中,这很好,因为您是从第二步重新回到第一步.
This starts your "mainDialog" over. In your example, this is fine, because you're restarting from the 2nd step back to the first.
ChoicePrompt
自动验证用户是否使用有效选项进行响应,但是您可以传递自己的自定义验证器.像这样:
ChoicePrompt
automatically validates whether or not the user responds with a valid option, but you can pass in your own custom validator. Something like:
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".相反,您可以执行以下操作:
Other Issues
Really, though, you shouldn't prompt your user with the option to select "dialog b" if it isn't ready. You could, instead, do something like:
var choices = new List<Choice>
{
new Choice
{
Value = "Open Dialog A",
}
};
if (bIsReady)
{
choices.Add(new Choice
{
Value = "Open Dialog B",
});
};
这篇关于BotFramework V4:RepromptDialogAsync不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!