1

This is the sample on Botframework v4 docs. But it does not work. It says "Can't Render Card" on the Microsoft bot emulator. What i'm trying to do is a carouselCard but this simple card from Microsoft's sample is already not working.

    {
  "type": "message",
  "text": "Plain text is ok, but sometimes I long for more...",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.0",
        "body": [
          {
            "type": "TextBlock",
            "text": "Hello World!",
            "size": "large"
          },
          {
            "type": "TextBlock",
            "text": "*Sincerely yours,*"
          },
          {
            "type": "TextBlock",
            "text": "Adaptive Cards",
            "separation": "none"
          }
        ],
        "actions": [
          {
            "type": "Action.OpenUrl",
            "url": "http://adaptivecards.io",
            "title": "Learn More"
          }
        ]
      }
    }
  ]
}

However, if i remove the top part of the code this code works:

  {
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "text": "Hello World!",
      "size": "large"
    },
    {
      "type": "TextBlock",
      "text": "*Sincerely yours,*"
    },
    {
      "type": "TextBlock",
      "text": "Adaptive Cards",
      "separation": "none"
    }
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "url": "http://adaptivecards.io",
      "title": "Learn More"
    }
  ]
}

This is how i call the card. Is there a better way to do this?

 public class GetNameAndAgeDialog : WaterfallDialog
    {

        private readonly string _cards = @".\Resources\TryCarouselCard.json";

        private static Attachment CreateAdaptiveCardAttachment(string filePath)
        {
            var adaptiveCardJson = File.ReadAllText(filePath);
            var adaptiveCardAttachment = new Attachment()
            {
                ContentType = "application/vnd.microsoft.card.adaptive",
                Content = JsonConvert.DeserializeObject(adaptiveCardJson),
            };
            return adaptiveCardAttachment;
        }

        public GetNameAndAgeDialog(string dialogId, IEnumerable<WaterfallStep> steps = null) : base(dialogId, steps)
        {

            AddStep(async (stepContext, cancellationToken) =>
            {
                var cardAttachment = CreateAdaptiveCardAttachment(_cards);
                var reply = stepContext.Context.Activity.CreateReply();
                reply.Attachments = new List<Attachment>() { cardAttachment };
                await stepContext.Context.SendActivityAsync(reply, cancellationToken);
                return await stepContext.ContinueDialogAsync();
            });
         }
      }
user10860402
  • 912
  • 1
  • 10
  • 34

1 Answers1

1

The "top part" of the first block of JSON you posted is the card contained within an activity. The second block of JSON posted is indeed just the card itself and what you'd want to put into an Attachment.

As for your code, it looks correct to me. I might consider caching the attachment JSON as you probably don't want to hit the file system every time you want to display the card, but that would just be an optimization.

I'm unclear if you are experiencing any further problems or just looking for validation of the approach now. If you are still experiencing a problem please update the question with some more details and I'll update my answer to try and help.

Drew Marsh
  • 33,111
  • 3
  • 82
  • 100
  • I am experiencing problems sir as the first code won't render on the bot emulator. It says "Can' render card" when i run it on the emulator. But when i remove the top part, which is the second code the bot emulator renders it and i can see the card. My problem is i want to make a carousel card so i think i need the top part of the code. – user10860402 Jan 07 '19 at 04:37
  • I managed to make a carousel card using C# and not json file. By the way this is my repo sir if you have time can you check for improvements. Thank you https://github.com/bnj123/azureBot – user10860402 Jan 07 '19 at 09:23
  • Well I'm glad you got it working. It looks like you've moved to use Hero Cards instead of Adaptive Cards. You will often find that certain channels/clients simply don't have full support for Adaptive Cards yet. The emulator and web client tend to support a majority of features, but perhaps something you were doing previously wasn't supported yet. – Drew Marsh Jan 07 '19 at 21:13
  • 1
    That makes a lot of sense thank you for everything you've helped me sir Drew! By the way what is the difference between "cancellationToken: cancellationToken" and "cancellationToken"? And what is its importance? – user10860402 Jan 08 '19 at 00:16
  • In `cancellationToken: cancellationToken` the name preceding the colon is the name of the parameter in the method you are calling. This is needed to disambiguate when a particular method has a lot of optional parameters and you're not necessarily passing them in order. Unfortunately several of the APIs in the Bot Builder SDK got a little too comfortable w/using optional parameters instead of providing multiple overloads. Now devs are have to be more verbose in disambiguating parameters. Some of these APIs can be smoothed out over time, but others cannot be fixed without breaking changes. – Drew Marsh Jan 08 '19 at 00:56