简体   繁体   English

如何将用户在自适应卡中输入的输入检索到C#代码以及如何调用提交按钮上的下一个意图

[英]How to retrieve user entered input in adaptive card to the c# code and how to call next intent on submit button click

I have a date picker adaptive card which I call during an intent call. 我有一个日期选择器自适应卡,可以在意向通话中调用它。 I am not getting as to how can I get value entered by the user and pass it to my bot luis where I will be having an intent which will get triggered with those values 我不知道如何获取用户输入的值并将其传递给我的机器人路易斯,在那里我将有一个意图被这些值触发

I have tried parsing the adaptive card json but I want the updated json with user entered values in it on submit button click. 我尝试解析自适应卡json,但是我希望在提交按钮单击时使用用户输入的值来更新json。

private Attachment CreateAdaptiveCardAttachment()
{
    // combine path for cross platform support
    string[] paths = { ".", "Cards", "AddingLeaveDetails.json" };
    string fullPath = Path.Combine(paths);
    var adaptiveCard = File.ReadAllText(fullPath);
    return new Attachment()
    {
        ContentType = "application/vnd.microsoft.card.adaptive",
        Content = JsonConvert.DeserializeObject(adaptiveCard),
    };
}

private Activity CreateResponse(IActivity activity, Attachment attachment)
{
    var response = ((Activity)activity).CreateReply();
    response.Attachments = new List<Attachment>() { attachmen`enter code here`t };
    return response;
}

@NikhilBansal, You can skip the "Waterfall Dialog" part of this answer (it's more for posterity), and head to the "Capture User Input" section. @NikhilBansal,您可以跳过此答案的“瀑布对话框”部分(更多用于后代),然后转到“捕获用户输入”部分。 It will likely be helpful to read the "Additional Context" and "Additional Resources" links, as well. 同样,阅读“其他上下文”和“其他资源”链接也可能会有所帮助。

Using Adaptive Cards with Waterfall Dialogs 瀑布对话框中使用自适应卡

Natively, Adaptive Cards don't work like prompts. 本地,自适应卡不能像提示一样工作。 With a prompt, the prompt will display and wait for user input before continuing. 带有提示,提示将显示并等待用户输入,然后继续。 But with Adaptive Cards (even if it contains an input box and a submit button), there is no code in an Adaptive Card that will cause a Waterfall Dialog to wait for user input before continuing the dialog. 但是对于自适应卡(即使它包含一个输入框和一个提交按钮),自适应卡中也没有代码,这会使瀑布对话框在继续对话框之前先等待用户输入。

So, if you're using an Adaptive Card that takes user input, you generally want to handle whatever the user submits outside of the context of a Waterfall Dialog. 因此,如果您正在使用需要用户输入的自适应卡,则通常需要处理用户在“瀑布对话框”上下文之外提交的所有内容。

That being said, if you want to use an Adaptive Card as part of a Waterfall Dialog, there is a workaround. 话虽如此,如果您想在瀑布对话框中使用自适应卡,则有一种解决方法。 Basically, you: 基本上,您:

  1. Display the Adaptive Card 显示自适应卡
  2. Display a Text Prompt 显示文字提示
  3. Convert the user's Adaptive Card input into the input of a Text Prompt 将用户的自适应卡输入转换为文本提示的输入

In your Waterfall Dialog class (steps 1 and 2): 在“瀑布对话框”类中(步骤1和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)
    {
        // Do something with step.result
        // Adaptive Card submissions are objects, so you likely need to JObject.Parse(step.result)
        await stepContext.Context.SendActivityAsync($"INPUT: {stepContext.Result}");
        return await stepContext.NextAsync();
    }

Capture User Input 捕获用户输入

In your main bot class ( <your-bot>.cs ), under OnTurnAsync() , near the beginning of the method, somewhere before await dialogContext.ContinueDialogAsync(cancellationToken) is called (step 3): 在您的主要bot类( <your-bot>.cs )中的OnTurnAsync() ,在该方法的开头附近,在await dialogContext.ContinueDialogAsync(cancellationToken)之前的某个位置(步骤3):

var activity = turnContext.Activity;

if (string.IsNullOrWhiteSpace(activity.Text) && activity.Value != null)
{
    activity.Text = JsonConvert.SerializeObject(activity.Value);
}

Update: For your code, specifically, you need to directly modify turnContext before sending it to your recognizer. 更新:具体来说,对于您的代码,您需要在将turnContext发送到识别turnContext之前直接对其进行修改。 Since RecognizeAsync doesn't work with objects, we need to ensure we send the appropriate value. 由于RecognizeAsync不适用于对象,因此我们需要确保发送适当的值。 Something like: 就像是:

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    // Capture input from adaptive card
    if (string.IsNullOrEmpty(turnContext.Activity.Text) && turnContext.Activity.Value != null)
    {
        // Conditionally convert based off of input ID of Adaptive Card
        if ((turnContext.Activity.Value as JObject)["<adaptiveCardInputId>"] != null)
        {
            turnContext.Activity.Text = (turnContext.Activity.Value as JObject)["<adaptiveCardInputId>"].ToString();
        }
    }
    // First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use.
    var recognizerResult = await _botServices.Dispatch.RecognizeAsync(turnContext, cancellationToken);

    // Top intent tell us which cognitive service to use.
    var topIntent = recognizerResult.GetTopScoringIntent();

    // Next, we call the dispatcher with the top intent.
    await DispatchToTopIntentAsync(turnContext, topIntent.intent, recognizerResult, cancellationToken);
}

The reason the code two blocks above didn't work is just because it wasn't set up for your code. 上面两个代码块不起作用的原因仅仅是因为没有为您的代码设置代码。 RecognizeAsync looks at turnContext.Activity.Text , which is null for an adaptive card (since adaptive card inputs come in Activity.Value . So, this new code sets turnContext.Activity.Text to turnContext.Activity.Value . However, to send it to the recognizer, you need it to be a string and not an object, so be sure to change <adaptiveCardInputId> to whatever ID you have on your adaptive card. RecognizeAsync查看turnContext.Activity.Text ,这对于自适应卡为null(因为自适应卡输入来自Activity.Value 。因此,此新代码将turnContext.Activity.Text设置为turnContext.Activity.Value ,但是要发送它对于识别器,您需要将其作为字符串而不是对象,因此请确保将<adaptiveCardInputId>更改为您在自适应卡上拥有的ID。

Additional Context 附加上下文

Adaptive Cards send their Submit results a little different than regular user text. 自适应卡发送的“提交”结果与常规用户文本略有不同。 When a user types in the chat and sends a normal message, it ends up in Context.Activity.Text . 当用户键入聊天并发送正常消息时,它最终出现在Context.Activity.Text When a user fills out an input on an Adaptive Card, it ends up in Context.Activity.Value , which is an object where the key names are the id in your card and the values are the field values in the adaptive card. 当用户填写自适应卡上的输入时,它会以Context.Activity.Value结尾,该对象是键名称是您卡中的id ,而值是自适应卡中的字段值的对象。

For example, the json: 例如,json:

{
    "type": "AdaptiveCard",
    "body": [
        {
            "type": "TextBlock",
            "text": "Test Adaptive Card"
        },
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": "Text:"
                        }
                    ],
                    "width": 20
                },
                {
                    "type": "Column",
                    "items": [
                        {
                            "type": "Input.Text",
                            "id": "userText",
                            "placeholder": "Enter Some Text"
                        }
                    ],
                    "width": 80
                }
            ]
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "Submit"
        }
    ],
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.0"
}

.. creates a card that looks like: ..创建一张看起来像这样的卡片:

测试自适应卡

If a user enters "Testing Testing 123" in the text box and hits Submit, Context.Activity will look something like: 如果用户在文本框中输入“ Testing Testing 123”,然后单击Submit,则Context.Activity类似于:

{ type: 'message',
  value: { userText: 'Testing Testing 123' },
  from: { id: 'xxxxxxxx-05d4-478a-9daa-9b18c79bb66b', name: 'User' },
  locale: '',
  channelData: { postback: true },
  channelId: 'emulator',
  conversation: { id: 'xxxxxxxx-182b-11e9-be61-091ac0e3a4ac|livechat' },
  id: 'xxxxxxxx-182b-11e9-ad8e-63b45e3ebfa7',
  localTimestamp: 2019-01-14T18:39:21.000Z,
  recipient: { id: '1', name: 'Bot', role: 'bot' },
  timestamp: 2019-01-14T18:39:21.773Z,
  serviceUrl: 'http://localhost:58453' }

The user submission can be seen in Context.Activity.Value.userText . 用户提交可以在Context.Activity.Value.userText看到。

Note that adaptive card submissions are sent as a postBack, which means that the submission data doesn't appear in the chat window as part of the conversation--it stays on the Adaptive Card. 请注意,自适应卡提交是作为postBack发送的,这意味着提交数据不会作为对话的一部分出现在聊天窗口中,而是保留在自适应卡上。


Additional Resources 其他资源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从自适应卡检索输入数据? - How to retrieve input data from an adaptive card? 在自适应卡片中,用户提交时如何切换可见性? - In Adaptive Card, how can I ToggleVisibility when user submit? c#如何单击此提交按钮? - c# How to click this submit button? 单击使用V4 C#开发的chatbot中的自适应卡中的Submit之后,如何解决与Web聊天通道中的500错误代码相关的问题? - How to fix issue related to 500 error code in web chat channel after clicking submit in Adaptive card in chatbot developed using V4 C#? 如何验证自适应卡片机器人框架 v4(瀑布模型)c# 中的输入字段 - How to validate input fields in adaptive card bot framework v4 (waterfall model) c# 如何在 C# 中使用 Linq to JSON 在单击按钮时检索下一个和上一个 ID - How to retrieve the next and previous ids on a button click using Linq to JSON in C# MS Chat Bot-如何从我的C#代码访问自定义自适应卡属性 - MS Chat Bot --How to access custom adaptive card properties from my C# code 如何在.NET Core C#中填充一些输入文本并单击提交按钮来抓取网站 - How to scrape website with filling some input text and click submit button in .NET Core C# 如何点击<input>键入按钮 C# - How to click on <input> type button C# 单击提交按钮时,自适应卡片中的输入值会刷新 - Input values in adaptive cards are getting refreshed on submit button click
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM