Search code examples
botframeworkadaptive-cards

Adaptive Card - DateInput and SubmitAction


Main Issue

I am using Adaptive Cards in Microsoft Bot Framework. I ran into a problem, where I do not know how to obtain the value from the DateInput after the user selects the date he wants. Below is my code currently:

public async Task StartAsync(IDialogContext context)
    {
        string pIdentifier = serviceFactory.ProfileService.GetPatientIdentifier(nric);
        string response = serviceFactory.DentalAppointmentService.GetSlotSearchDates(nric,apptId,caseNumber, institutionCode, pIdentifier);
        string[] split = response.Split(' ');
        DateTime earliestStartDate = DateTime.ParseExact(split[0], "yyyy'-'MM'-'dd'T'HH':'mm':'ss", CultureInfo.InvariantCulture);
        DateTime latestEndDate = DateTime.ParseExact(split[1], "yyyy'-'MM'-'dd'T'HH':'mm':'ss", CultureInfo.InvariantCulture);

        await context.PostAsync("Your appointment can only be rescheduled within this period " + earliestStartDate.ToShortDateString() + " to " + latestEndDate.ToShortDateString());



        AdaptiveCard card = new AdaptiveCard();

        card.Body.Add(new TextBlock()
        {
            Text = "Enter new Date",
            Size = TextSize.Large,
            Weight = TextWeight.Bolder
        });

        DateInput input = new DateInput()
        {
            Id = "Date",
            Placeholder = "New Date"
        };

        card.Body.Add(input);

        card.Actions.Add(new SubmitAction()
        {
            Title = "Submit"
        });

        Attachment cardAttachment = new Attachment()
        {
            ContentType = AdaptiveCard.ContentType,
            Content = card
        };

        var message = context.MakeMessage();
        message.Attachments = new List<Attachment>();
        message.Attachments.Add(cardAttachment);

        await context.PostAsync(message);
        context.Wait(this.MessageReceivedAsync);
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    {
        var temp = await result as Activity;
        string date = temp.Text;


        //DateTime newDate = DateTime.ParseExact(value.ToString(), "yyyy'-'MM'-'dd'T'HH':'mm':'ss", CultureInfo.InvariantCulture);

        Debug.WriteLine("Entered Msg received Async:" + date);
        await context.PostAsync(date);
    }

Current Error Thrown

I'm running into this issue currently and I'm not able to find a solution:

Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in mscorlib.dll


Solution

  • The value of the date from the DatePicker will come into the bot as a JObject on the activity.Value

    The following code will pull the date from either the .Text property, or the .Value:

    public async Task StartAsync(IDialogContext context)
    {
        context.Wait(this.MessageReceivedAsync);
    }
    
    
    public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
        var temp = await result as Activity;
    
        DateTime dateTime;
        var datePresent = DateTime.TryParse(temp.Text, out dateTime);
        if (!datePresent && temp.Value != null)
        {
            var jObjectValue = temp.Value as JObject;
    
            var dateAsString = jObjectValue.Value<string>("Date");
            if (!string.IsNullOrEmpty(dateAsString))
            {
                dateTime = DateTime.ParseExact(dateAsString, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                datePresent = true;
            }
        }
    
        if (!datePresent)
        {
            //since the user did not send a date, show the card
            AdaptiveCard card = new AdaptiveCard();
    
            card.Body.Add(new AdaptiveTextBlock()
            {
                Text = "Enter new Date",
                Size = AdaptiveTextSize.Large,
                Weight = AdaptiveTextWeight.Bolder
            });
    
            AdaptiveDateInput input = new AdaptiveDateInput()
            {
                Id = "Date",
                Placeholder = "New Date"
            };
    
            card.Body.Add(input);
    
            card.Actions.Add(new AdaptiveSubmitAction()
            {
                Title = "Submit"
            });
    
            Attachment cardAttachment = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content = card
            };
    
            var message = context.MakeMessage();
            message.Attachments = new List<Attachment>();
            message.Attachments.Add(cardAttachment);
    
            await context.PostAsync(message);
        }
        else
        {
            await context.PostAsync($"Date Entered: {dateTime}");
        }
    
        context.Wait(this.MessageReceivedAsync);
    }
    

    Also, please upgrade your AdaptiveCards library to version 1.0: https://www.nuget.org/packages/AdaptiveCards/