我使用 SDK .net Core 2.2 虚拟助手模板在 C# 中创建聊天机器人,该模板具有 1 个主对话框和多个对话框(组件对话框)。每个组件对话框调用另一个组件对话框。 假设我有 MainDialog,2 个组件对话框名为 ComponentDialog1,ComponentDialog2。
我正在使用 DialogsTriggerState 来了解要在整个机器人中触发哪个组件对话框。
主对话框代码:我在主对话框的路由异步方法中调用组件对话框1。
protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
{
var triggerState = await _triggerStateAccessor.GetAsync(dc.Context, () => new DialogsTriggerState());
await dc.BeginDialogAsync(nameof(ComponentDialog1), triggerState);
var turnResult = EndOfTurn;
if (turnResult != EndOfTurn)
{
await CompleteAsync(dc);
}
}
组件对话框1代码:我有3个瀑布步骤,其中第二步将根据机器人状态调用特定的"组件对话框"。假设我正在触发"组件对话框2"。
private async Task<DialogTurnResult> TriggerToSpecificComponentDialogAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var triggerState = await _DialogsTriggerStateAccessor.GetAsync(stepContext.Context, () => null);
if (triggerState.TriggerDialogId.ToString().ToLower() == "componentdialog2")
{
return await stepContext.BeginDialogAsync(nameof(ComponentDialog2), triggerState);
}
else if (triggerState.TriggerDialogId.ToString().ToLower() == "componentdialog3")
{
return await stepContext.BeginDialogAsync(nameof(ComponentDialog3), triggerState);
}
else
{
return await stepContext.NextAsync();
}
}
组件对话框2代码:我有2个瀑布步骤,显示自适应卡片并从卡片和结束对话框中获取值(组件对话框2)
private async Task<DialogTurnResult> DisplayCardAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Display the Adaptive Card
var cardPath = Path.Combine(".", "AdaptiveCard.json");
var cardJson = File.ReadAllText(cardPath);
var cardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(cardJson),
};
var message = MessageFactory.Text("");
message.Attachments = new List<Attachment>() { cardAttachment };
await stepContext.Context.SendActivityAsync(message, cancellationToken);
// Create the text prompt
var opts = new PromptOptions
{
Prompt = new Activity
{
Type = ActivityTypes.Message,
Text = "waiting for user input...", // You can comment this out if you don't want to display any text. Still works.
}
};
// Display a Text Prompt and wait for input
return await stepContext.PromptAsync(nameof(TextPrompt), opts);
}
private async Task<DialogTurnResult> HandleResponseAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
await stepContext.Context.SendActivityAsync($"INPUT: {stepContext.Result}");
//I am doing some logic and may continue to next steps also from here, but as I am stuck here i am ending dialog.
return await stepContext.EndDialogAsync();
}
问题:在第 1 步的"ComponentDialog2"中单击自适应卡片提交后,代码(控件)没有指向第 2 步"HandleResponseAsync",这应该发生,因为我提供了提示并等待输入。
实际输出:我在机器人中既没有得到任何输出也没有错误。
预期输出:
1)从组件对话框2显示给机器人:输入:无论我提交什么
2)当我在组件对话框2中结束对话框时,控件(代码)应该返回到组件对话框1,并应该转到组件对话框1的第3个瀑布步骤。
自适应卡片示例
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "Let us know your feedback"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"actions": [
{
"type": "Action.Submit",
"title": "Good",
"data": "good"
},
{
"type": "Action.Submit",
"title": "Average",
"data": "avaerage"
}
,{
"type": "Action.Submit",
"title": "Bad",
"data": "bad"
}
]
}
请帮助我如何实现
经过大量测试,我相当确定您在某处错过了此呼叫(它应该以某种方式被调用OnMessageAsync()
:
var results = await dialogContext.ContinueDialogAsync(cancellationToken);
核心机器人示例执行此操作的方式是将其添加到DialogExtensions
中,这将在OnMessageAsync()
中调用
更新:我还注意到,如果await ConversationState.SaveChangesAsync(turnContext, true, cancellationToken);
在OnTurnAsync()
中但在OnDialogAsync()
中打开(或者如果它不在任何一个位置),则可能会发生这种情况;您还希望确保它通常设置为false
而不是true
。