Search code examples
c#azurebotframeworkbotsformflow

KeyNotFoundException on confirm prompt in dynamic FormFlow


SDK Version: 3.16.1.38846 Code: .Net

Issue Description

We are using Field.SetDefine to define in real time field buttons based on the value gotten from calling a service. To be specific, we have a Source field and a Destination field, the buttons for the Destination and Source field are defined based on the result from the services When a user completes the form, but clicks No on the Confirmation prompt, he gets the following exception:

Failure to complete form. Exception: The given key was not present in the dictionary.

   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.Bot.Builder.FormFlow.Advanced.Field`1.ValueDescription(Object value)
   at Microsoft.Bot.Builder.FormFlow.Advanced.RecognizeEnumeration`1.<>c__DisplayClass2_0.<.ctor>b__0(Object value)
   at Microsoft.Bot.Builder.FormFlow.Advanced.RecognizeEnumeration`1.ValueDescription(Object value)
   at Microsoft.Bot.Builder.FormFlow.Advanced.Prompter`1.ValueDescription(IField`1 field, Object value, String format)
   at Microsoft.Bot.Builder.FormFlow.Advanced.Prompter`1.ExpandTemplate(String template, String currentChoice, String noValue, T state, IField`1 field, Object[] args, IList`1& buttons)
   at Microsoft.Bot.Builder.FormFlow.Advanced.Prompter`1.Prompt(T state, IField`1 field, Object[] args)
   at Microsoft.Bot.Builder.FormFlow.Advanced.NavigationField`1..ctor(String name, String startField, IForm`1 form, T state, FormState formState, Fields`1 fields)
   at Microsoft.Bot.Builder.FormFlow.Advanced.NavigationStep`1..ctor(String startField, IForm`1 form, T state, FormState formState)
   at Microsoft.Bot.Builder.FormFlow.FormDialog`1.<MessageReceived>d__16.MoveNext()
   --- End of inner exception stack trace ---

We think this probably happens because the FormFlow code is trying to access the value of the field but the list of buttons changed and now this value no longer exists in the list.

How can I avoid this exception.

Example Code

The complete bot code that reproduces the issue.

public class DynaForm
{
    public static ICollection<string> CustomerAccounts { get; set; }
    public string Destination { get; set; }
    public string source { get; set; }


    public static IForm<DynaForm> BuildFormAsync()
    {
        return new FormBuilder<DynaForm>()
            .Message("Welcome to the simple sandwich order bot!")
            .Field(new FieldReflector<DynaForm>(nameof(source))
                .SetType(null)
                .SetDefine((state, field) =>
                {
                foreach (var item in CustomerAccounts)
               {
                   field
                       .AddDescription(item,item)
                       .AddTerms(item, item);
               }
               return Task.FromResult(true);                   
                })             
                .SetPrompt(new PromptAttribute("Select the source account \n {||} \n") { ChoiceStyle = ChoiceStyleOptions.Buttons })
                .SetAllowsMultiple(false)
                )                  
            .Field(new FieldReflector<DynaForm>(nameof(Destination))
                .SetType(null)
                .SetDependencies(nameof(source))
                .SetDefine((state, field) =>
                {
                foreach (var item in CustomerAccounts)
                {
                  field
                    .AddDescription(item, item)
                    .AddTerms(item, item);
                }
                return Task.FromResult(true);
                })
                .SetPrompt(new PromptAttribute("Select the destination account \n {||} \n") { ChoiceStyle = ChoiceStyleOptions.Buttons })                 
                .SetAllowsMultiple(false)                 
                )
            .Confirm("Do you want to continue? {||}")           
            .Build();   
    }
}

Expected Behavior

When user selects No on confirm prompt, the form field should be displayed for the users to select the field to change.

enter image description here


Solution

  • I responded to you via GitHub, as it looks like you have the same question posted twice: https://github.com/Microsoft/BotBuilder/issues/5060