如何创建具有情景文本值的自适应卡片?

How to create adaptive cards with situational text values?

我目前正在尝试在 Waterfall Dialog 中为我的一个机器人创建一个自适应卡片,它会在呈现时显示名称和搜索项(两个字符串)。我想使用的两个值都存储在我的对话框的 Context.Activity.Value 属性 中,所以我需要知道的是如何在创建过程中的某个时刻将这些值插入我的自适应卡,以便文本块的 "text" 值可以包含我的值。

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

下面是我制作自适应卡片的Waterfall Dialog中的步骤:

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
                }
            ]
        }
    ],

}

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

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

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

Handlebars.Compile(<Adaptive card template>);

Handlebars 作为 Nuget 包提供,您可以将其添加到项目中。

对于您的简单场景,我会采纳@MikeP 的建议。将来,如果您想在模板无法满足的情况下做一些更复杂的事情,那么您可以在拥有 installed the AdaptiveCard 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 
            // 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 模板更灵活,您可以在已知位置替换占位符标记。