Botbuilder-dotnet: Microsoft Bot Framework V 4.1.5 c# Adaptive Card AdaptiveSubmitAction not working.

Created on 30 Nov 2018  路  21Comments  路  Source: microsoft/botbuilder-dotnet

Microsoft Bot Framework V 4.1.5 Adaptive Card AdaptiveSubmitAction not working.

Version

Microsoft Bot Builder 4.1.5
Adaptive Cards 1.1.0
Microsoft.ASPNetCore.All 2.1.4

Describe the bug

I have created an adaptive card sample with c# with Enterprise Bot Template.
I have used AdaptiveCards SDK V1.1.5

Following is my code for creating the adaptive card.

public Attachment CreateAdaptiveCardWithEntryNew()
        {
            var card = new AdaptiveCard("1.0");
            List<AdaptiveElement> AdaptiveElementRemaining1 = new List<AdaptiveElement>
            {
                new AdaptiveColumnSet()
                {
                    Columns = new List<AdaptiveColumn>()
                    {
                        new AdaptiveColumn()
                        {
                            Items = new List<AdaptiveElement>()
                            {
                                new AdaptiveTextBlock()
                                {
                                    Text= "name",
                                    Weight= AdaptiveTextWeight.Bolder,
                                    Separator=true,
                                    Size = AdaptiveTextSize.Large,
                                },
                                new AdaptiveTextInput()
                                {
                                    Id = "Your Name",
                                    Speak = "<s>Please Enter Your Name</s>",
                                    Placeholder = "Please Enter Your Name",
                                    Style = AdaptiveTextInputStyle.Text
                                }
                            },
                            Separator =true,
                        }
                    }                   
                }
            };
            AdaptiveContainer adaptiveContainerRemaining1 = new AdaptiveContainer();
            adaptiveContainerRemaining1.Items = AdaptiveElementRemaining1;
            card.Body.Add(adaptiveContainerRemaining1);
            card.Actions.Add(new AdaptiveSubmitAction()
            {
                Title = "submit",
                Type = AdaptiveSubmitAction.TypeName,
                Data = "submit",
                Id = "submit",
                DataJson = "{\"submit\":\"submit\"}",
                Speak = "<s>submit</s>"
            }
            );
            card.Actions.Add(new AdaptiveOpenUrlAction()
            {
                Url = new Uri("http://www.google.com")
            });
            Attachment attachment = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content = card
            };
            return attachment;
        }

This method renders my card perfectly on different channels. However, when I click on the submit button for the callback, I am getting the below exception in the OnTurnAsyncMethod.

And here is the line in which I m getting the exception.

public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
/*in below line i am getting an error when i click on button.*/   
            var dc = await _dialogs.CreateContextAsync(turnContext);
            var result = await dc.ContinueDialogAsync();
            if (result.Status == DialogTurnStatus.Empty)
            {
                if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate)
                {
                    var activity = turnContext.Activity.AsConversationUpdateActivity();
                    // if conversation update is not from the bot.
                    if (!activity.MembersAdded.Any(m => m.Id == activity.Recipient.Id))
                    {
                        await dc.BeginDialogAsync(nameof(MainDialog));
                    }
                }               
                else
                {
                    // if (turnContext.Activity.Type != "trigger")
                    await dc.BeginDialogAsync(nameof(MainDialog));
                }
            }
   }

Exception details

exception.messgae - > Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObject. Path 'PoC.DialogStack.$values[0].State.dialogs.DialogStack.$values[0].State.dialogs.DialogStack.$values[0].State.options.Prompt.attachments.$values[0].content.body'.

exception.path -> PoC.DialogStack.$values[0].State.dialogs.DialogStack.$values[0].State.dialogs.DialogStack.$values[0].State.options.Prompt.attachments.$values[0].content.body

exception.stackTrace ->
at Newtonsoft.Json.Linq.JArray.Load(JsonReader reader, JsonLoadSettings settings)
at AdaptiveCards.IgnoreEmptyItemsConverter1.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer) at Newtonsoft.Json.Linq.JToken.ToObject[T](JsonSerializer jsonSerializer) at Microsoft.Bot.Builder.MemoryStorage.ReadAsync(String[] keys, CancellationToken cancellationToken) in D:\a\1\s\libraries\Microsoft.Bot.Builder\MemoryStorage.cs:line 75 at Microsoft.Bot.Builder.BotState.LoadAsync(ITurnContext turnContext, Boolean force, CancellationToken cancellationToken) in D:\a\1\s\libraries\Microsoft.Bot.Builder\BotState.cs:line 67 at Microsoft.Bot.Builder.BotState.BotStatePropertyAccessor1.GetAsync(ITurnContext turnContext, Func`1 defaultValueFactory, CancellationToken cancellationToken) in D:\a1\s\libraries\Microsoft.Bot.Builder\BotState.cs:line 284
at Microsoft.Bot.Builder.Dialogs.DialogSet.CreateContextAsync(ITurnContext turnContext, CancellationToken cancellationToken) in D:\a1\s\libraries\Microsoft.Bot.Builder.Dialogs\DialogSet.cs:line 64
at NttData.PA.Chatbot.PoC.ChatbotPoC.OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) in C:Users\roshan.parmar\source\repos\softweb\sw-ms-bot-nttdatapa\NttData.PA.Chatbot.PoC\NttData.PA.Chatbot.PoC\ChatbotPoC.cs:line 74
at Microsoft.Bot.Builder.AutoSaveStateMiddleware.OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken) in D:\a1\s\libraries\Microsoft.Bot.Builder\AutoSaveStateMiddleware.cs:line 60
at Microsoft.Bot.Builder.TranscriptLoggerMiddleware.OnTurnAsync(ITurnContext turnContext, NextDelegate nextTurn, CancellationToken cancellationToken) in D:\a1\s\libraries\Microsoft.Bot.Builder\TranscriptLoggerMiddleware.cs:line 105
at Microsoft.Bot.Builder.MiddlewareSet.ReceiveActivityWithStatusAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) in D:\a1\s\libraries\Microsoft.Bot.Builder\MiddlewareSet.cs:line 55
at Microsoft.Bot.Builder.BotAdapter.RunPipelineAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) in D:\a1\s\libraries\Microsoft.Bot.Builder\BotAdapter.cs:line 167

Expected behavior

It should return the value on the button click.

[bug]

All 21 comments

This may not be related to your issue, but when you define an AdaptiveSubmitAction you don't need to set the type because it's set automatically. Also I would avoid using both Data and DataJson and just use one or the other. I tend to think DataJson is more reliable.

As for what's causing the problem, it would be helpful to know what's being done with the attachment you're creating. Is this card being sent at a certain point in a dialog? I've had problems where an adaptive submit action has caused CreateContextAsync to throw an error because it's not expecting the activity's text property to be empty, like if the dialog is using a prompt and therefore expecting a response in the text property.

Ok @v-kydela , here are the details on what i am doing. I created a dialog in which i am trying to gather information via adaptive card in different waterfall steps.
So, i created a dialog named welcomedialog and calling this dialog from the maindialog.

welcome dialog

```C#
public const string TextPrompt = "TextPrompt";
private IStatePropertyAccessor _accessor;
public WelcomeDialog(BotServices botServices, IStatePropertyAccessor accessor) : base(botServices, nameof(WelcomeDialog))
{
_accessor = accessor;
InitialDialogId = nameof(WelcomeDialog);
var waterfallStep = new WaterfallStep[]
{
welcome,
welcomeResult
};
AddDialog(new WaterfallDialog(InitialDialogId, waterfallStep));
AddDialog(new TextPrompt(TextPrompt));
}
public async Task welcome(WaterfallStepContext sc, CancellationToken cancellationToken)
{
var reply = sc.Context.Activity.CreateReply();
reply.Attachments.Add(CreateAdaptiveCardWithEntryNew());
return await sc.PromptAsync(TextPrompt, new PromptOptions()
{
Prompt = reply
});
}
public async Task welcomeResult(WaterfallStepContext sc, CancellationToken cancellationToken)
{
var data = sc.Context.Activity.Value;
return await sc.CancelAllDialogsAsync();
}
public Attachment CreateAdaptiveCardWithEntryNew()
{
var card = new AdaptiveCard("1.0");
List AdaptiveElementRemaining1 = new List
{
new AdaptiveColumnSet()
{
Columns = new List()
{
new AdaptiveColumn()
{
Items = new List()
{
new AdaptiveTextBlock()
{
Text= "name",
Weight= AdaptiveTextWeight.Bolder,
Separator=true,
Size = AdaptiveTextSize.Large,
},
new AdaptiveTextInput()
{
Id = "submit",
Placeholder = "Please Enter Your Name",
Style = AdaptiveTextInputStyle.Text
}
},
Separator =true,
}
}
}
};
AdaptiveContainer adaptiveContainerRemaining1 = new AdaptiveContainer();
adaptiveContainerRemaining1.Items = AdaptiveElementRemaining1;
card.Body.Add(adaptiveContainerRemaining1);
card.Actions.Add(new AdaptiveSubmitAction()
{
Title = "submit",
Id = "submit",
Data = Newtonsoft.Json.Linq.JObject.FromObject(new { button = "three" })
//DataJson = "{\"hi\":\"hi\"}",
}
);
card.Actions.Add(new AdaptiveOpenUrlAction()
{
Url = new Uri("http://www.google.com")
});
Attachment attachment = new Attachment()
{
ContentType = AdaptiveCard.ContentType,
Content = card
};
return attachment;
}

In this dialog, I am expecting the output in the welcomeResult waterfall step. But it gives me an error as mentioned above in the `OnTurnAsync` method as shown above
![error1](https://user-images.githubusercontent.com/19162518/49324595-ea32f200-f556-11e8-9616-daa960af48bc.png)

**maindialog routeasync method**

```c#
protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
{
    var intent = Dispatch.Intent.l_General;
    if (intent == Dispatch.Intent.l_General)
    {
        // If dispatch result is general luis model
        _services.LuisServices.TryGetValue("testluis", out var luisService);
        if (luisService == null)
        {
            throw new Exception("The specified LUIS Model could not be found in your Bot Services configuration.");
        }
        else
        {
            var result = await luisService.RecognizeAsync<General>(dc.Context, CancellationToken.None);
            var generalIntent = result?.TopIntent().intent;
            // switch on general intents
            switch (generalIntent)
            {
                case General.Intent.Greeting:
                    {
                        await dc.BeginDialogAsync(nameof(welcomeDialog));
                        break;
                        // send greeting response
                        await _responder.ReplyWith(dc.Context, MainResponses.Greeting);
                        break;
                    }
                case General.Intent.None:
                default:
                    {
                        // No intent was identified, send confused message
                        await _responder.ReplyWith(dc.Context, MainResponses.Confused);
                        break;
                    }
            }
        }
    }
}

This is related to a bug in the AdaptiveCards package: https://github.com/Microsoft/AdaptiveCards/issues/2148

Try constructing your attachment like this:

c# Attachment attachment = new Attachment() { ContentType = AdaptiveCard.ContentType, Content = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(card)), };

Thanks, @v-kydela this has solved the issue and i am getting response as below

activity.value = "{{
  "button": "three",
  "submit": "roshan text data"
}}"

Now, I am facing one another problem and an exception is thrown and i think that is because of Enterprise Bot template. The exception is Value cannot be null. Parameter name: utterance. And that is due to Activity.Text is null.

detailed description

When i click on the submit button, the request is passed from
InteruptableDialog -> OnContinueDialogAsync method, than to
EnterpriseDialog ->OnDialogInterruptionAsync method, here in this method
var luisResult = await luisService.RecognizeAsync<General>(dc.Context, cancellationToken);
is called to identify the intent. and this passes the control to
TelemtryLuisRecognizer ->RecognizeAsync(ITurnContext context, CancellationToken ct, bool logOriginalMessage = false) method.

Here in RecognizeAsync method
var recognizerResult = await base.RecognizeAsync(context, ct);
is called to identify the intent. However, as the text paramter is blank and null in the activity object (as we are getting the data in the value parameter in activity) it throws the below error.

Excpetion Message
Value cannot be null.
Parameter name: utterance

Source: Microsoft.Bot.Builder.AI.Luis

Activity object that is passed in the method

{"type":"message","id":"kg5k1278h908","timestamp":"2018-12-03T06:34:20.63+00:00","localTimestamp":"2018-12-03T12:04:20+05:30","serviceUrl":"http://localhost:50702","channelId":"emulator","from":{"id":"default-user","name":"User","role":null},"conversation":{"isGroup":null,"conversationType":null,"id":"gmj6hmb69gif","name":null,"role":null},"recipient":{"id":"default-bot","name":"Bot","role":null},"textFormat":null,"attachmentLayout":null,"membersAdded":null,"membersRemoved":null,"reactionsAdded":null,"reactionsRemoved":null,"topicName":null,"historyDisclosed":null,"locale":"en-US","text":null,"speak":null,"inputHint":null,"summary":null,"suggestedActions":null,"attachments":null,"entities":null,"channelData":null,"action":null,"replyToId":null,"label":null,"valueType":null,"value":{"button":"three","submit":"roshan text data"},"name":null,"relatesTo":null,"code":null,"expiration":null,"importance":nul
l,"deliveryMode":null,"listenFor":null,"textHighlights":null,"semanticAction":null}

expected behaviour

base.RecognizeAsync method should handle the cases when the data is passed in the activity.Value instead of activity.Text . Please let me know how can i handle this.

Stack Trace
at Microsoft.Bot.Builder.AI.Luis.LuisRecognizer.d__23.MoveNext() in D:\a1\s\libraries\Microsoft.Bot.Builder.AI.LUIS\LuisRecognizer.cs:line 449
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.AI.Luis.LuisRecognizer.d__10.MoveNext() in D:\a1\s\libraries\Microsoft.Bot.Builder.AI.LUIS\LuisRecognizer.cs:line 104
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at EnterpriseBot2.TelemetryLuisRecognizer.<RecognizeAsync>d__81.MoveNext() in C:Users\Administrator\source\repos\EnterpriseBot2\EnterpriseBot2\Middleware\Telemetry\TelemetryLuisRecognizer.cs:line 131
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at EnterpriseBot2.EnterpriseDialog.<OnDialogInterruptionAsync>d__4.MoveNext() in C:\Users\Administrator\source\repos\EnterpriseBot2\EnterpriseBot2\Dialogs\Shared\EnterpriseDialog.cs:line 39 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at EnterpriseBot2.InterruptableDialog.d__1.MoveNext() in C:Users\Administrator\source\repos\EnterpriseBot2\EnterpriseBot2\Dialogs\Shared\InterruptableDialog.cs:line 19
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.Dialogs.ComponentDialog.d__8.MoveNext() in D:\a1\s\libraries\Microsoft.Bot.Builder.Dialogs\ComponentDialog.cs:line 65
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.Dialogs.DialogContext.d__17.MoveNext() in D:\a1\s\libraries\Microsoft.Bot.Builder.Dialogs\DialogContext.cs:line 130
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at EnterpriseBot2.RouterDialog.<OnContinueDialogAsync>d__2.MoveNext() in C:\Users\Administrator\source\repos\EnterpriseBot2\EnterpriseBot2\Dialogs\Shared\RouterDialog.cs:line 29 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.ComponentDialog.<ContinueDialogAsync>d__8.MoveNext() in D:\a\1\s\libraries\Microsoft.Bot.Builder.Dialogs\ComponentDialog.cs:line 65 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.Dialogs.DialogContext.<ContinueDialogAsync>d__17.MoveNext() in D:\a\1\s\libraries\Microsoft.Bot.Builder.Dialogs\DialogContext.cs:line 130 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at EnterpriseBot2.EnterpriseBot2.d__5.MoveNext() in C:Users\Administrator\source\repos\EnterpriseBot2\EnterpriseBot2\EnterpriseBot2.cs:line 50
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.AutoSaveStateMiddleware.d__7.MoveNext() in D:\a1\s\libraries\Microsoft.Bot.Builder\AutoSaveStateMiddleware.cs:line 60
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.ShowTypingMiddleware.d__3.MoveNext() in D:\a1\s\libraries\Microsoft.Bot.Builder\ShowTypingMiddleware.cs:line 71
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.MiddlewareSet.d__3.MoveNext() in D:\a1\s\libraries\Microsoft.Bot.Builder\MiddlewareSet.cs:line 55
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.BotAdapter.d__13.MoveNext() in D:\a1\s\libraries\Microsoft.Bot.Builder\BotAdapter.cs:line 167

Here's a trick for you. The activity's Text property isn't read-only. First you should simplify your submit action:
```c#
card.Actions.Add(new AdaptiveSubmitAction
{
Title = "submit",
Id = "submit",
}

Then put this at the beginning of your `OnTurnAsync`:
```c#
if (string.IsNullOrEmpty(turnContext.Activity.Text))
{
    dynamic value = turnContext.Activity.Value;
    string text = value["submit"];  // The property will be named after your text input's ID
    text = string.IsNullOrEmpty(text) ? "." : text; // In case the text input is empty
    turnContext.Activity.Text = text;
}

@sw-ms-roshanparmar - Did this solve your issue?

Yes, it solved. However, i need to modify code in this way, so that it work for the conversationupdate activity type also.

 if (string.IsNullOrEmpty(turnContext.Activity.Text))
      {
        dynamic value = turnContext.Activity.Value;
        if (value != null)
        {
          string text = value["submit"];  // The property will be named after your text input's ID
          text = string.IsNullOrEmpty(text) ? "." : text; // In case the text input is empty
          turnContext.Activity.Text = text;
        }
      }

Well done. I'm closing this issue now.

Here's a trick for you. The activity's Text property isn't read-only. First you should simplify your submit action:

card.Actions.Add(new AdaptiveSubmitAction
{
  Title = "submit",
  Id = "submit",
}

Then put this at the beginning of your OnTurnAsync:

if (string.IsNullOrEmpty(turnContext.Activity.Text))
{
    dynamic value = turnContext.Activity.Value;
    string text = value["submit"];    // The property will be named after your text input's ID
    text = string.IsNullOrEmpty(text) ? "." : text; // In case the text input is empty
    turnContext.Activity.Text = text;
}

thanks this is helpful. I am beginner in .NET and bot frameworks :)
Do you have the equivalent code for SDK 3 ? i think there is no turnContext in v3. I tried to find full example on the internet but i couldn't

@soso-maitha - Remember that the activity schema has remained unchanged between V3 and V4. In V3, you will have no need to access the activity through a turn context because your messages controller will get passed the activity directly. So just replace turnContext.Activity with activity.

Is it even possible to make this work for Skype channel?
I've tried setting a lot of different properties but nothing seems to work.

All I need is for an adaptive card submit button to send an imBack activity to the bot.

We have adaptive cards that work well on multiple channels with objects on Data property, but since Skype doesn't support postBacks, I was doing a workaround to handle imBacks after seeing this answer

The data property of the action may be a string or it may be an object. A string is passed back to your bot as a Bot Builder SDK imBack activity, and an object is passed as a postBack activity.

That makes sense and would be enough for my use case (and i think many others who rely on adaptive cards?).

However, after multiple attempts, skype channel just doesn't send anything to bot on adaptive card button click.

I know NET SDK prepares adaptive cards as images + maps buttons before sending them to Facebook, and it looks like the same happens for Skype.
Maybe it's just the NET SDK code that is forcing the Type = ActionTypes.PostBack and if it would send ImBack instead, it would work on skype?

Sorry for posting on this closed issue but there are so many repos, I have no clue where to open an issue related to this.

@AndreMantas - It's true that Adaptive Cards allow you to use imBack by setting a string as the Data property. However, it does seem that Skype doesn't handle this well. You can post an issue in the Adaptive Cards repo if you like.

@v-kydela do you know if c# sdk does any transformation for sending adaptive card to skype? Or the adaptive card is it just rendered in skype as they want?

I ask this because I'm thinking if I could replicate what c# sdk does, like sending hero cards with the adaptive cards as image, where i can control the card action types for imBack or some other work around.

Thanks in advance.

It does appear that Skype is able to handle card actions in hero cards well, so using a hero card instead would make sense. The BotBuilder SDK does not perform any transformations on Adaptive Cards to accommodate specific channels. Any transformations only occur after the card has reached the connector. If you would like more help, please open a new issue.

@v-kydela connector issues are also in this repo?

@AndreMantas - You might also consider the Botframework-Services repo: https://github.com/Microsoft/BotFramework-Services/

May I please know what source are you referring to write the C# code for the adaptive cards?

I am using AdaptiveCards from nuget.

I am using AdaptiveCards from nuget.

No, I mean what documentation or blogs have you referred to write this code? Are there any good sources of information for writing code of adaptive card inside C# code? Because only JSON is given everywhere!!

@aarohi-001 - The AdaptiveCards NuGet package provides models you can use in C#. There's no trick to it. The objects you instantiate in C# follow the same schema as an ordinary JSON Adaptive Card. Please have a look at my latest blog post to better understand Adaptive Cards: https://blog.botframework.com/2019/07/02/using-adaptive-cards-with-the-microsoft-bot-framework/

If you still have questions, please post a question on Stack Overflow.

@aarohi-001 - The AdaptiveCards NuGet package provides models you can use in C#. There's no trick to it. The objects you instantiate in C# follow the same schema as an ordinary JSON Adaptive Card. Please have a look at my latest blog post to better understand Adaptive Cards: https://blog.botframework.com/2019/07/02/using-adaptive-cards-with-the-microsoft-bot-framework/

If you still have questions, please post a question on Stack Overflow.

Okay, thank you so much!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sgellock picture sgellock  路  4Comments

drub0y picture drub0y  路  3Comments

markbeau picture markbeau  路  6Comments

cmayomsft picture cmayomsft  路  6Comments

MarceloRGonc picture MarceloRGonc  路  6Comments