【问题标题】:How to create adaptive cards with situational text values?如何创建具有情境文本值的自适应卡片?
【发布时间】:2019-10-31 12:57:59
【问题描述】:

我目前正在尝试在瀑布对话框中为我的一个机器人创建一个自适应卡片,该卡片将在渲染时显示名称和搜索项(两个字符串)。我要使用的两个值都存储在对话框的 Context.Activity.Value 属性中,所以我只需要知道如何在创建自适应卡的某个时间点将这些值插入到自适应卡中,以便“文本”文本块的值可以包含我的值。

我已经研究过在自适应卡架构中使用空 JSON 对象,我可以在创建自适应卡时以某种方式填充这些对象,但还没有弄清楚如何插入所述值。我是 C# 和 Bot Framework 的相对初学者,所以我不知道该尝试什么。

下面是我的瀑布对话框中制作自适应卡片的步骤:

private async Task<DialogTurnResult> AdaptiveCardTest(WaterfallStepContext stepContext, 
CancellationToken cancellationToken)
        {
            var introCard = File.ReadAllText("./Content/AdaptiveCardTest.json");

            var card = AdaptiveCard.FromJson(introCard).Card;
            var attachment = new Attachment(AdaptiveCard.ContentType, content: card);

            var response = MessageFactory.Attachment(attachment, ssml: card.Speak, 
            inputHint: InputHints.AcceptingInput);

            await stepContext.Context.SendActivityAsync(response);

            return await stepContext.NextAsync();
        }

AdaptiveCardTest.json 是自适应卡的 json 文件。目前它只有一个带有一些文本的图像弹出窗口,其中包括我希望用户名和搜索项去的占位符。占位符链接在那里是因为实际链接非常长。

{
    "type": "AdaptiveCard",
    "id": "NewUserGreeting",
    "backgroundImage": "image_url_placeholder"
    "body": [
        {
            "type": "Container",
            "items": [
                {
                    "type": "Image",
                    "url": "image_url_placeholder_2"",
                    "size": "Stretch"
                }
            ]
        },


        {
            "type": "Container",
            "spacing": "None",
            "backgroundImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAXCAIAAACAiijJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVDhPY1RgL2SgDDBBaQrAqBEIMGoEAowagQCjRiDAqBEIQLERDAwAIisAxhgAwtEAAAAASUVORK5CYII=",
            "items": [
                {
                    "type": "TextBlock",
                    "id": "title",
                    "spacing": "Medium",
                    "size": "Large",
                    "weight": "Bolder",
                    "color": "Light",
                    "text": "Hi, I'm **your** Virtual Assistant",
                    "wrap": true
                },
                {
                    "type": "TextBlock",
                    "id": "body",
                    "size": "Medium",
                    "color": "Light",
                    "text": "The user {{Name}} would like to know more about {{SearchItem}}.",
                    "wrap": true
                }
            ]
        }
    ],

}

任何帮助将不胜感激,谢谢!

【问题讨论】:

    标签: c# botframework adaptive-cards


    【解决方案1】:

    对于您的简单场景,我会接受@MikeP 的建议。将来,如果您想在模板不够用的情况下做一些更复杂的事情,那么您可以在拥有installedAdaptiveCard NuGet 包后使用 .NET SDK 动态构建自适应卡。

    .NET SDK 的文档是 pretty limited,但 AdaptiveCard 对象的属性通常与其对应的 JSON 保持一致。

    一个例子是:

    const string ISO8601Format = "yyyy-MM-dd";
    string text = "dynamic-text-here;
    
    DateTime today = DateTime.Today;
    string todayAsIso = today.ToString(ISO8601Format);
    
    // Create card
    AdaptiveCard adaptiveCard = new AdaptiveCard("1.0")
    {
        Body =
        {
            new AdaptiveContainer
            {
                Items =
                {
                    new AdaptiveTextBlock
                    {
                        Text = question,
                        Wrap = true
                    },
                    new AdaptiveDateInput
                    {
                        // This Id matches the property in DialogValueDto so it will automatically be set
                        Id = "UserInput",
                        Value = todayAsIso,
                        Min = today.AddDays(-7).ToString(ISO8601Format),
                        Max = todayAsIso,
                        Placeholder = todayAsIso
                    }
                }
            }
        },
        Actions = new List<AdaptiveAction>
        {
            new AdaptiveSubmitAction
            {
                // Data can be an object but this will require the value provided for the 
                // Content property to be serialised it to a string
                // as per this answer https://stackoverflow.com/a/56297792/5209435
                // See the attachment block below for how this is handled
                Data = "your-submit-data",
                Title = "Confirm",
                Type = "Action.Submit"
            }
        }
    };
    
    // Create message attachment
    Attachment attachment = new Attachment
    {
        ContentType = AdaptiveCard.ContentType,
        // Trick to get Adapative Cards to work with prompts as per https://github.com/Microsoft/botbuilder-dotnet/issues/614#issuecomment-443549810
        Content = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(adaptiveCard))
    };
    
    cardActivity.Attachments.Add(attachment);
    
    // Send the message
    context.SendActivityAsync(cardActivity);
    

    因为ItemsActions 是集合,您可以在代码中使用条件逻辑来根据运行时的某些条件构建这些集合,然后将构建集合传递给ItemsActions,这将允许您比在已知位置替换占位符标记的 JSON 模板更灵活。

    【讨论】:

    • 这很棒,我一定会尝试一下。谢谢!
    • 因为您可能会遇到与我在检索自适应卡提交值方面遇到的相同问题,我将在此处留下this answer,如果您在瀑布内运行自适应卡但想要它要作为提示功能,即捕获用户输入,那么您需要参考this question and answer plus the links in it(一些浅显的阅读哈哈。)
    • 我确实有!我从这里使用 mdrichardson 的修复程序:stackoverflow.com/questions/56004289/…。我仍然没有让文本输入进入 handleresponseasync。有什么想法吗?
    • 两个选项:1) 不要在postbackActivity 上设置Text 属性,而是尝试直接在dc.Context.Activity.Text 上设置它,这样你就可以避免这条线await dc.Context.SendActivityAsync(postbackActivity); 2 ) 检查 MainDialog.cs 中的 OnEventAsync 方法,确保没有任何东西阻止您的代码进入 if (forward) 然后实际执行 dc.ContinueDialogAsync() 调用 - 我遇到了这个问题,所以值得放一个调试器在此处并在提交自适应卡时逐步执行。
    【解决方案2】:

    这是我过去使用Handlebars 所做的事情,这是用模型中的属性替换自适应卡 JSON 中的标记的好方法。只需确保自适应卡片 JSON 中的令牌与模型属性匹配即可

    查看他们的网站了解更多详情,但这只是一个例子:

    Handlebars.Compile(<Adaptive card template>);
    

    Handlebars 以 Nuget 包的形式提供,您可以将其添加到项目中。

    【讨论】:

      猜你喜欢
      • 2021-02-05
      • 1970-01-01
      • 2018-12-28
      • 1970-01-01
      • 2019-07-26
      • 2020-04-24
      • 2021-12-17
      • 2021-05-01
      • 1970-01-01
      相关资源
      最近更新 更多