Introduction
The Bot Framework supports different types of rich cards and provides a richer interaction experience to the user. In this article, I will show how to integrate adaptive card UI design in a Bot application. The Adaptive Card contains a combination of text, speech, images, buttons, and input controls. Adaptive Cards are created using the JSON format specified in the Adaptive Cards schema and Microsoft provided Microsoft.AdaptiveCards NuGet package for .NET Developer to building cards and handles the serialization.

Prerequisite
I have explained about Bot framework installation, deployment, and implementation in the below articles -
- Getting Started with Chatbot Using Azure Bot Service
- Getting Started with Bots Using Visual Studio 2017
- Deploying A Bot to Azure Using Visual Studio 2017
- How to Create ChatBot In Xamarin
- Getting Started with Dialog Using Microsoft Bot Framework
- Getting Started with Prompt Dialog Using Microsoft Bot Framework
- Getting Started With Conversational Forms And FormFlow Using Microsoft Bot Framework
- Getting Started With Customizing A FormFlow Using Microsoft Bot Framework
- Sending Bot Reply Message With Attachment Using Bot Framework
- Getting Started With Hero Card Design Using Microsoft Bot Framework
- Getting Started With Thumbnail Card Design Using Microsoft Bot Framework
Create New Bot Application
Let's create a new bot application using Visual Studio 2017. Open Visual Studio > Select File > Create New Project (Ctrl + Shift +N) > Select Bot application.


Install AdaptiveCard Nuget package
Microsoft.AdaptiveCards library implements classes for building and serializing adaptive card objects and Visual Studio IntelliSense will help us to implement Adaptive cards in the bot application.
Right-click on Solution, select Manage NuGet Package for Solution > Search “ Microsoft AdaptiveCards” > select Project and install the package.

Create New AdaptiveCardDialog Class
Step 1
You can create a new AdaptiveCardDialog class to show the Adaptive dialog. Rightclick on Project, select Add New Item, create a class that is marked with the [Serializable] attribute (so the dialog can be serialized to state), and implement the IDialog interface.
- using System;
- using System.Threading.Tasks;
- using Microsoft.Bot.Builder.Dialogs;
- using Microsoft.Bot.Connector;
- using System.IO;
- using System.Web;
- using System.Collections.Generic;
- namespace BotAdaptiveCard.Dialogs
- {
- [Serializable]
- public class AdaptiveCardDialog: IDialog<object>
- {
Step 2
IDialog interface has only StartAsync() method. StartAsync() is called when the dialog becomes active. The method passes the IDialogContext object, used to manage the conversation.
- public async Task StartAsync(IDialogContext context)
- {
- context.Wait(this.MessageReceivedAsync);
- }
Step 3
Create a MessageReceivedAsync method and write the following code for the welcome message and to show the list of the demo options dialog.
- [Serializable]
- public class AdaptiveCardDialog : IDialog<object>
- {
- public Task StartAsync(IDialogContext context)
- {
- context.Wait(this.MessageReceivedAsync);
- return Task.CompletedTask;
- }
- private readonly IDictionary<string, string> options = new Dictionary<string, string>
- { "1", "1. Show Demo Adaptive Card " },
- { "2", "2. Show Demo for Adaptive Card Design with Column" },
- {"3" , "3. Input Adaptive card Design" }
- };
- public async virtual Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
- {
- var message = await result;
- var welcomeMessage = context.MakeMessage();
- welcomeMessage.Text = "Welcome to bot Adaptive Card Demo";
- await context.PostAsync(welcomeMessage);
- this.DisplayOptionsAsync(context);
- }
- public void DisplayOptionsAsync(IDialogContext context)
- {
- PromptDialog.Choice<string>(
- context,
- this.SelectedOptionAsync,
- this.options.Keys,
- "What Demo / Sample option would you like to see?",
- "Please select Valid option 1 to 6",
- 6,
- PromptStyle.PerLine,
- this.options.Values);
- }
- public async Task SelectedOptionAsync(IDialogContext context, IAwaitable<string> argument)
- {
- var message = await argument;
- var replyMessage = context.MakeMessage();
- Attachment attachment = null;
- switch (message)
- {
- case "1":
- attachment = CreateAdapativecard();
- replyMessage.Attachments = new List<Attachment> { attachment };
- break;
- case "2":
- attachment = CreateAdapativecardWithColumn();
- replyMessage.Attachments = new List<Attachment> { attachment };
- break;
- case "3":
- replyMessage.Attachments = new List<Attachment> { CreateAdapativecardWithColumn(), CreateAdaptiveCardwithEntry() };
- break;
- }
- await context.PostAsync(replyMessage);
- this.DisplayOptionsAsync(context);
- }
After the user enters the first message, our bot will reply with a welcome message and list of demo options. Then, it waits for user input like below.

Step 4 Design Adaptive Card
The Adaptive Cards are created using JSON but with Microsoft.AdaptiveCards NuGet, we can create them by composing card objects. We can create AdaptiveCard objects and attach to the attachment and post message to a message.

- public Attachment CreateAdapativecard()
- {
- AdaptiveCard card = new AdaptiveCard();
- // Specify speech for the card.
- card.Speak = "Suthahar J is a Technical Lead and C# Corner MVP. He has extensive 10+ years of experience working on different technologies, mostly in Microsoft space. His focus areas are Xamarin Cross Mobile Development ,UWP, SharePoint, Azure,Windows Mobile , Web , AI and Architecture. He writes about technology at his popular blog http://devenvexe.com";
- // Body content
- card.Body.Add(new Image()
- {
- Url = "https://i1.social.s-msft.com/profile/u/avatar.jpg?displayname=j%20suthahar&size=extralarge&version=88034ca2-9db8-46cd-b767-95d17658931a",
- Size = ImageSize.Small,
- Style = ImageStyle.Person,
- AltText = "Suthahar Profile"
- });
- // Add text to the card.
- card.Body.Add(new TextBlock()
- {
- Text = "Technical Lead and C# Corner MVP",
- Size = TextSize.Large,
- Weight = TextWeight.Bolder
- });
- // Add text to the card.
- card.Body.Add(new TextBlock()
- {
- Text = "[email protected]"
- });
- // Add text to the card.
- card.Body.Add(new TextBlock()
- {
- Text = "97XXXXXX12"
- });
- // Create the attachment with adapative card.
- Attachment attachment = new Attachment()
- {
- ContentType = AdaptiveCard.ContentType,
- Content = card
- };
- return attachment;
- }
The above code will generate following adaptive card and reply to the user

Step 5 Design Adaptive Card with Column:
The Adaptive Cards contain many elements that allow designing UI content in a common and consistent way.
- Container - A Container is a CardElement which contains a list of CardElements that are logically grouped.
- ColumnSet and Column - The columnSet element adds the ability to have a set of Column objects and align the column object.
- FactSet - The FactSet element is displayed row and column like a tabular form.
- TextBlock - The TextBlock element allows for the inclusion of text, we can modify font sizes, weight, and color.
- ImageSet and Image - The ImageSet allows for the inclusion of collection images like a photo set, and the Image element allows for the inclusion of images.

The following code shows adding multiple columns and design of the UI Adaptive Card.
- public Attachment CreateAdapativecardWithColumn()
- {
- AdaptiveCard card = new AdaptiveCard()
- {
- Body = new List<CardElement>()
- {
- // Container
- new Container()
- {
- Speak = "<s>Hello!</s><s>Suthahar J is a Technical Lead and C# Corner MVP. He has extensive 10+ years of experience working on different technologies, mostly in Microsoft space. His focus areas are Xamarin Cross Mobile Development ,UWP, SharePoint, Azure,Windows Mobile , Web , AI and Architecture. He writes about technology at his popular blog http://devenvexe.com</s>",
- Items = new List<CardElement>()
- {
- // first column
- new ColumnSet()
- {
- Columns = new List<Column>()
- {
- new Column()
- {
- Size = ColumnSize.Auto,
- Items = new List<CardElement>()
- {
- new Image()
- {
- Url = "https://i1.social.s-msft.com/profile/u/avatar.jpg?displayname=j%20suthahar&size=extralarge&version=88034ca2-9db8-46cd-b767-95d17658931a",
- Size = ImageSize.Small,
- Style = ImageStyle.Person
- }
- }
- },
- new Column()
- {
- Size = "300",
- Items = new List<CardElement>()
- {
- new TextBlock()
- {
- Text = "Suthahar Jegatheesan MCA",
- Weight = TextWeight.Bolder,
- IsSubtle = true
- },
- new TextBlock()
- {
- Text = "[email protected]",
- Weight = TextWeight.Lighter,
- IsSubtle = true
- },
- new TextBlock()
- {
- Text = "97420XXXX2",
- Weight = TextWeight.Lighter,
- IsSubtle = true
- },
- new TextBlock()
- {
- Text = "https://www.devenvexe.com",
- Weight = TextWeight.Lighter,
- IsSubtle = true
- }
- }
- }
- }
- },
- // second column
- new ColumnSet()
- {
- Columns = new List<Column>()
- {
- new Column()
- {
- Size = ColumnSize.Auto,
- Separation =SeparationStyle.Strong,
- Items = new List<CardElement>()
- {
- new TextBlock()
- {
- Text = "Suthahar J is a Technical Lead and C# Corner MVP. He has extensive 10+ years of experience working on different technologies, mostly in Microsoft space. His focus areas are Xamarin Cross Mobile Development ,UWP, SharePoint, Azure,Windows Mobile , Web , AI and Architecture. He writes about technology at his popular blog http://devenvexe.com",
- Wrap = true
- }
- }
- }
- }
- }
- }
- }
- },
- };
- Attachment attachment = new Attachment()
- {
- ContentType = AdaptiveCard.ContentType,
- Content = card
- };
- return attachment;
- }
The above code will generate the following card design and reply message.

Step 6 Adaptive Card Design with Input Control
The Adaptive Cards can include input controls for collecting the information from the user. It will support the following input controls - Text, Date, Time, Number, and for selecting options(choice set) and toggle.
The following sample code is included collecting basic information from the users with an action button.
- Text – Collect the text content from the user
- Date - Collect a Date from the user
- Time - Collect a Time from the user
- Number - Collect a Number from the user
- ChoiceSet - provide the user with a set of choices and have them pick
- ToggleChoice - provide the user with a single choice between two items and have them pick
- public Attachment CreateAdaptiveCardwithEntry()
- {
- var card = new AdaptiveCard()
- {
- Body = new List<CardElement>()
- {
- // Hotels Search form
- new TextBlock() { Text = "Please Share your detail for contact:" },
- new TextInput()
- {
- Id = "Your Name",
- Speak = "<s>Please Enter Your Name</s>",
- Placeholder = "Please Enter Your Name",
- Style = TextInputStyle.Text
- },
- new TextBlock() { Text = "When your Free" },
- new DateInput()
- {
- Id = "Free",
- Placeholder ="Your free Date"
- },
- new TextBlock() { Text = "Your Experence" },
- new NumberInput()
- {
- Id = "No of Year experence",
- Min = 1,
- Max = 20,
- },
- new TextBlock() { Text = "Email" },
- new TextInput()
- {
- Id = "Email",
- Speak = "<s>Please Enter Your email</s>",
- Placeholder = "Please Enter Your email",
- Style = TextInputStyle.Text
- },
- new TextBlock() { Text = "Phone" },
- new TextInput()
- {
- Id = "Phone",
- Speak = "<s>Please Enter Your phone</s>",
- Placeholder = "Please Enter Your Phone",
- Style = TextInputStyle.Text
- },
- },
- Actions = new List<ActionBase>()
- {
- new SubmitAction()
- {
- Title = "Contact",
- Speak = "<s>Contact</s>",
- }
- }
- };
- Attachment attachment = new Attachment()
- {
- ContentType = AdaptiveCard.ContentType,
- Content = card
- };
- return attachment;
- }
The above code will return the following adaptive card design.

Run Bot Application
The emulator is a desktop application that lets us test and debugs our bot on localhost. Now, you can click on "Run the application" in Visual Studio and execute it in the browser.

Test Application on Bot Emulator
You can follow the below steps to test your bot application.
- Open Bot Emulator.
- Copy the above localhost URL and paste it in emulator e.g. - http://localHost:3979
- You can append the /api/messages in the above URL; e.g. - http://localHost:3979/api/messages.
- You won't need to specify Microsoft App ID and Microsoft App Password for localhost testing. So, click on "Connect".

Summary
In this article, you learned how to create a Bot application using Visual Studio 2017 and create the adaptive design and input using Bot framework. If you have any questions/feedback/ issues, please write in the comment box.

davePosted Sep 25, 2020, 11:16 PM
Hi,I am new to bot framework I am using visual Studio 2017 and after installing bot template sdk in project template folder, I opened visual Studio but bot framework template is not showing like u provide in example it is showing under web and asking to choose one template among five(.core template).. Is anything I am missing?
Harsh GuptaPosted Sep 6, 2019, 1:24 PM
Really helpful, thanks!
Jumping BoyPosted Jun 6, 2019, 10:59 AM
I need to run my query and get result and prompt all result
Jumping BoyPosted Jun 6, 2019, 10:58 AM
How to do "prompt": "[SqlConnectionBuilder]", using adaptive card
Ankitha KSPosted May 3, 2019, 1:05 AM
How to use animations in adaptive cards?
nasrin nazarPosted Mar 24, 2019, 9:23 AM
Hello Sir, Thanks for your great article. But I was facing issues in installing adaptive cards. Finally I installed it. But now it shows errors like this: " The type or namespace name 'CardElement' could not be found (are you missing a using directive or an assembly reference?)" same error is there for every element in adaptive cards like, TimeInput, dateinput etc. How could I resolve it and make use of your code?
Rupesh MacherlaPosted Jan 3, 2019, 6:40 AM
Hello sir, glad to meet you. Very thankful to your articles on Microsoft Bot framework. Currently I am researching on Microsoft bot framework. In that we are developing voice input bot by using Microsoft cognitive services( Speech-to-Text ). We implemented that and tested in local bot emulator that time it works fine after that we deployed that code into Azure bot. In Azure testing also it works fine. But my problem is that we are testing that speech bot separately by using Web chat channel link that time we are not getting mic symbol. We tried many ways but we didn't get. If possible could you please suggest me to resolve this. Very grateful to you..
Ankur TandonPosted Nov 29, 2018, 12:53 PM
Hello, i want to know can we provide ids or any custom attributes to the adaptive card to provide style or how can host config to style and render the adaptive card. My main aim is to style the adaptive cards with custom css. As they dont have any id i cannot apply css. Either i can apply id to the adaptive card or use hostconfig settings to implement style. I am using microsoft bot framework and direct line channel.
chandana nadellaPosted Nov 27, 2018, 7:29 AM
Hi Suthahar J it was a great article and could create an adaptive Card but How to submit the data to azure storage on click of submit and also after submitting the data it should come out of the loop. Is there an separate article regarding this .
Mark HawkinsWoodPosted Sep 20, 2018, 9:26 AM
Hello Suthahar, I'm not much of a dev myself but I've built a Bot using the Azure BotFramework with LUIS integration for Natural Language Processing, I have as a call to action for one of my dialog resolutions a SQL DB call which is working successfully by taking the user query, and querying the DB, then returning info on that person. However I want the output to be an Adaptive Card, how can I do this without having my message routed to a separate AdaptiveCardDialog? (As I'll lose Luis functionality)
Prasanna MandemPosted Jun 26, 2018, 5:20 AM
Hello Suthahar,your work is very helpful to me.Can you please explain me how to add these adapative cards input to database
aaa aaaPosted May 7, 2018, 3:40 AM
Hello Suthahar, i appreciate your work here. How can i trigger another task method via SubmitAction. For example i want to show the message "Your message has been taken into account". I can't find the link between the submit action and the call to another method.
Rakesh PatelPosted Mar 8, 2018, 10:01 AM
Hello Suthahar, It is very nice post. Can you please explain me how can we set hyper link on any of the text and that will open link in new window?Thanks, Rakesh
prasath febPosted Jan 30, 2018, 4:10 AM
I given like above.but values not getting from adaptive control (text box).
prasath febPosted Jan 30, 2018, 4:09 AM
Actions = new List<ActionBase>() { new SubmitAction() { Title = "Contact", Speak = "<s>Contact</s>", DataJson= ("{ \"Type\": \"SaveFunction\" }") }
prasath febPosted Jan 24, 2018, 1:45 AM
HI suthahar.. how to handle(trigger) submit action through voice message.
Dawson BrittoPosted Oct 23, 2017, 1:28 AM
Hi Suthahar,Again a great article! Just want to know, how would you handle a submit action here to collect the form data? My intentions here are to collect the form data and send it as an email using SendGrid. Thanks in advance Regards Daws
Vishal PrajapatiPosted Oct 12, 2017, 5:11 AM
Awesome sir..........
Ramesh PalanivelPosted Oct 12, 2017, 3:57 AM
Excellent article Sir!..