Как создать адаптивные карты с ситуативными текстовыми значениями? - PullRequest
3 голосов
/ 18 июня 2019

В настоящее время я пытаюсь создать адаптивную карту в диалоге водопада для одного из моих ботов, который будет отображать имя и элемент поиска (обе строки) при визуализации. Оба значения, которые я хочу использовать, хранятся в свойстве 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
                }
            ]
        }
    ],

}

Любая помощь будет принята с благодарностью, спасибо!

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Для вашего простого сценария я бы согласился с предложением @ MikeP. В будущем, если вы захотите сделать что-то более сложное, когда шаблон будет недостаточным, вы можете динамически создать Adaptive Card, используя .NET SDK, если у вас установлена ​​ AdaptiveCard Пакет NuGet.

Документация по .NET SDK довольно ограничена , но свойства объекта 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);

Поскольку Items и Actions являются коллекциями, вы можете иметь условную логику в своем коде для создания этих коллекций на основе некоторого условия во время выполнения, а затем передавать коллекцию сборки в Items или Actions, что позволит вам больше гибкости, чем наличие шаблона JSON, в котором вы заменяете токены-заполнители в известном месте.

0 голосов
/ 18 июня 2019

Это то, что я делал в прошлом, используя Handlebars , который является хорошим способом замены токенов в JSON вашей адаптивной карты свойствами из модели.Просто убедитесь, что токены в вашей адаптивной карте JSON соответствуют свойствам модели

Для получения более подробной информации посетите их сайт, но это всего лишь один из вариантов:

Handlebars.Compile(<Adaptive card template>);

Доступны руликак пакет Nuget, который вы можете добавить в свой проект.

...