我将botframework 4(c#)与Qnamaker一起使用来制作qnabot。如果qna-service返回的答案多于1个,我希望该机器人能够提出其他问题。
因此,我创建了一个执行该操作的对话框。但是,接下来要遍历所有步骤,直到结尾,然后我调用context.EndDialogAsync(),它会引发“字典中不存在给定键。”-
如果我在此后在聊天中输入内容,它将再次运行对话步骤,然后冲洗并重复。
任何人都知道可能是什么问题?我愿意使用代码,我只是不知道可能导致错误的代码。
我正在尝试尽可能地遵循此示例:https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.cafe-bot
一个区别是,如果像我在示例中所做的那样将它添加到MainDispatcher中,则我无法使机器人找到我的对话框(找不到)。但是,如果我将其添加到“类”中:IBot可以正常工作。可以关联吗?
感谢有关如何调试的帮助或提示,谢谢!
这将设置对话框,瀑布中的所有步骤都将起作用,直到我到达最后一个并尝试调用EndDialogAsync。
public OptionsDialog(IStatePropertyAccessor<QnaProperty> qnaAccessors, IEnumerable<WaterfallStep> steps = null, string dialogId = null)
: base(Name)
{
QnAAccessor = qnaAccessors ?? throw new ArgumentNullException(nameof(qnaAccessors));
var waterfallStepsOptions = new WaterfallStep[]
{
PromptQuestionAsync,
WriteAnswerAsync,
HelpfulResponseAsync,
};
AddDialog(new WaterfallDialog(WaterfallStepsName, waterfallStepsOptions));
ChoicePrompt choice = new ChoicePrompt(QuestionPromptName);
choice.Style = ListStyle.SuggestedAction;
AddDialog(choice);
AddDialog(new ChoicePrompt(HelpfulPromptName));
}
最后的瀑布步骤:
private async Task<DialogTurnResult> HelpfulResponseAsync(WaterfallStepContext stepContext,
CancellationToken cancellationToken)
{
var answer = (stepContext.Result as FoundChoice).Value;
if (answer == "Yes")
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Great!"), cancellationToken);
}
else
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Maybe try rephrasing your question else here's a link to the documentation: LINK"), cancellationToken);
}
return await stepContext.EndDialogAsync(cancellationToken);
}
启动该对话框的对话框如下所示:
public MainDialog(BotServices services, ConversationState conversationState, string dialogId = null)
: base(Name)
{
_services = services ?? throw new ArgumentNullException(nameof(services));
_qnaAccessor = conversationState.CreateProperty<QnaProperty>(QnaProperty);
_dialogAccessor = conversationState.CreateProperty<DialogState>(DialogProperty);
_dialogs = new DialogSet(_dialogAccessor);
}
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null,
CancellationToken cancellationToken = default(CancellationToken))
{
var response = await _services.QnAServices[QnaConfiguration].GetAnswersAsync(dc.Context);
var qnaProperty = await _qnaAccessor.GetAsync(dc.Context, () => new QnaProperty(response));
//var qnaProperty = await _qnaAccessor.SetAsync(dc.Context, response, cancellationToken);
if (response != null && response.Length > 1)
{
return await dc.BeginDialogAsync(OptionsDialog.Name, cancellationToken);
}
else if (response != null && response.Length == 1)
{
await dc.Context.SendActivityAsync(response[0].Answer, cancellationToken: cancellationToken);
}
else
{
var msg = @"No QnA Maker answers were found.";
await dc.Context.SendActivityAsync(msg, cancellationToken: cancellationToken);
}
return await dc.EndDialogAsync(cancellationToken);
}
编辑:
当我将逻辑从MainDispatcher Dialog移到IBot类时,它似乎起作用了,因此我认为问题可能出在在Ibot类而不是maindialog中实例化对话框时找到对话框。也许吗?