Data Binding in Adaptive Cards 2.0

In this article, we are going to learn what new feature is coming to Adaptive Card 2.0

In this article, we are going to learn what new feature is coming to Adaptive Card 2.0. In Adaptive Card, there are lots of new features to be released very soon. Here, I have highlighted only two new features.

1. Adaptive Card template language.
2. Adaptive Card template service.
 
First, we will learn about the template language, Then, in the next article, we will learn about Adaptive Card Template Service.

What is Adaptive Card?

 
Adaptive Cards are an open card exchange format enabling developers to exchange UI content in a common and consistent way. So far, both - the data and UI part -  are in a single package. There is no way to separate the data and UI part.  Well, Adaptive Cards 2.0 has a solution.

Adaptive Cards 2.0 has started supporting binding and the concept is called “Adaptive Cards template language.” The use of Template language enables the separation of data and view, and the library provides a final adaptive card combination of Data and the view.

Adaptive Card Binding


Binding property is defined into the “{““}” braces with the class name and the property name. The binding of the data within the body or actions sections of the card, not anywhere else.

In two different ways, we can implement the Binding concept.
  1. Define the data inside the Adaptive Card template
  2. Prepare the language-based class object and generate the Adaptive Card file.
Adaptive Card template

In this section, we are going to see why binding is required and how to implement the binding concept.
 
Let’s start with a simple example to understand the concept.
 
I have designed an adaptive card to display the school, master, and student name.
  1. {  
  2.     "type""AdaptiveCard",  
  3.     "version""1.0",  
  4.     "body": [  
  5.     {  
  6.       "type""TextBlock",  
  7.       "text""Welcome to C# Corner School"  
  8.     },  
  9.     {  
  10.       "type""TextBlock",  
  11.       "text""Teacher name is: Vinoth"  
  12.     },  
  13.     {  
  14.       "type""TextBlock",  
  15.       "text""And Student names: Rajendran,Sankar,Guru,Ramesh"  
  16.     }  
  17.     ]  
  18. }

Output

 
 
Dynamic data set
 
Display perfectly; no issues on that but still is in static data set, oh wait; you can create this card with different dataset in runtime, yes are you right but one more also you are doing. Any idea? Yep, preparing not only the data’s, in addition, preparing the UI part also. If UI is changing you have rebuild your application not only that if this card using any other platform those also get rebuild, Oh Big changes. Got it, to avoid this problem binding future implemented in the Adaptive card 2.0.
 
Example

Now we are going to separate the data and view. First prepare the dataset, which are data’s dynamically change.
 
In this Example school, teacher and students names change at runtime. Now we will prepare the data set, to define the dataset in the template file it should be in the $data section.

Create a class name with all property like below.
  1. "$data": {  
  2.     "school": {  
  3.       "name""C# Corner",  
  4.       "teacher": { "name""Vinoth" },  
  5.       "student": [  
  6.         {  
  7.           "name""Rajendran"  
  8.         },  
  9.         {  
  10.           "name""Sankar"  
  11.         },  
  12.         {  
  13.           "name""Guru"  
  14.         },  
  15.         {  
  16.           "name""Ramesh"  
  17.         }  
  18.       ]  
  19.     }  
Our data set is ready, next define the property name in the UI part, the property name should be defined with the {class.propertname } format.
  1. "body": [  
  2.     {  
  3.       "type""TextBlock",  
  4.       "text""Welcome to {school.name} School"  
  5.     },  
  6.     {  
  7.       "type""TextBlock",  
  8.       "text""teacher name is: {school.teacher.name}"  
  9.     },  
  10.     {  
  11.       "type""TextBlock",  
  12.       "text""And Student names: {school.student[0].name}, {school.student[1].name}, {school.student[2].name}"  
  13.     }  
  14.   ]  
Prepare the output

Once our Adaptive card template is ready to use the AdaptiveTransformer class to merge the data and the UI.

AdaptiveTransformer: AdaptiveTransformer is a new class introduced AdaptiveCard 2.0 this class is in preview, maybe the way of implementation will change in the final product.

Note:

We can define the data JSON and UI JSON in a separate file and use the Transform API function to get the final adaptive card. Incase both UI and data is in the same file, Read the data set in the file and pass to the Transform API to get final adaptive card.

In this sample, I have used both data and UI the same file, so we have to read the data set in the JSON file.
  1. var fileRead = File.ReadAllText("School.json");  
  2.   
  3. var item = (JObject) JsonConvert.DeserializeObject(fileRead);  
  4.   
  5. string classData = item["$data"].ToString();  
Finally use the Transform API function get the final Adaptive Card.
  1. AdaptiveTransformer transformer = new AdaptiveTransformer();  
  2. string cardJson = transformer.Transform(fileRead, classData);  
This sample I have prepare with Bot Framework 4.0 below code is complete function information
  1. private IMessageActivity CreateCard()  
  2.        {  
  3.   
  4.            var fileRead = File.ReadAllText("School.json");  
  5.            var item = (JObject) JsonConvert.DeserializeObject(fileRead);  
  6.            string classData = item["$data"].ToString();              
  7.   
  8.            AdaptiveTransformer transformer = new AdaptiveTransformer();  
  9.            string cardJson = transformer.Transform(fileRead, classData);  
  10.   
  11.            Attachment attachment = new Attachment();  
  12.            attachment.ContentType = "application/vnd.microsoft.card.adaptive";  
  13.            attachment.Content = JsonConvert.DeserializeObject(cardJson);  
  14.   
  15.            var attachments = new List<Attachment>();  
  16.            var reply = MessageFactory.Attachment(attachments);  
  17.            reply.Attachments.Add(attachment);  
  18.            return reply;  
  19.        }  
Output
 
 
 
I hope you can understand how to implement the data binding concept in Adaptive Card.

In the next article, we will learn how to use the language-based class object (ex: C# class object) to generate the Adaptive Card file.
 
Happy Reading. Happy coding.