首页 > 解决方案 > 在嵌套对话框中处理自适应卡片提交操作值

问题描述

我使用 SDK .net Core 2.2虚拟助手模板在 C# 中创建了聊天机器人,该模板具有 1 个主对话框和多个对话框(组件对话框)。每个组件对话框调用另一个组件对话框。假设我有 MainDialog,2 个名为 ComponentDialog1、ComponentDialog2 的组件对话框。

我正在使用 DialogsTriggerState 来了解要在整个机器人中触发哪个组件对话框。

主对话框代码:我在主对话框的RouteAsync方法中调用 ComponentDialog1。

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);
    }
}

ComponentDialog1 代码: 我有 3 个瀑布步骤,其中第二步将调用特定的“ComponentDialog”,具体取决于机器人状态。假设我正在触发“ComponentDialog2”。

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();
    }
}

ComponentDialog2 代码: 我有 2 个瀑布步骤,显示自适应卡并从卡和结束对话框中获取值(ComponentDialog2)

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();
}

问题:在第一步的“ComponentDialog2”中单击自适应卡提交后,代码(控件)未指向第二步“HandleResponseAsync”,这应该发生,因为我提供了提示并等待输入。

实际输出:我在机器人中既没有得到任何输出也没有错误。

预期输出:

1)从 ComponentDialog2 显示到机器人:输入:无论我提交什么

2)当我在 ComponentDialog2 中结束对话框时,控件(代码)应该返回到 ComponentDialog1 并应该转到 ComponentDialog1 的第 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"
    }
]
}

请帮助我如何实现

标签: c#botframeworkchatbotadaptive-cardswaterfall

解决方案


经过大量测试后,我相当确定您在某处错过了这个电话(它应该以某种方式被调用OnMessageAsync()

var results = await dialogContext.ContinueDialogAsync(cancellationToken);

Core Bot Sample执行此操作的方式是将其添加DialogExtensionsOnMessageAsync()


更新:我还注意到,如果await ConversationState.SaveChangesAsync(turnContext, true, cancellationToken);OnTurnAsync()但在OnDialogAsync()(或者如果它不在任何一个位置),就会发生这种情况;通常,您还想确保它设置为false而不是true


推荐阅读