JurgenW
JurgenW

Reputation: 317

Azure Bot Framework FormFlow complex forms

I'm trying to create a bot with the Azure Bot Framework that will ask for an unknown amount of complex objects (each will require three responses). But I don't know how to create a form for each of the complex objects within the rootform. See http://docs.botframework.com/sdkreference/csharp/forms.html. It states: "In order to handle a list of complex objects, you need to create a form for the top level C# class and also one for the complex object. You can use the Dialogs system to compose the forms together." That is what I dont know how to do.

public enum SystemSelection { SharePoint, BizTalk, Azure, Office365 };

public enum RequestType { Bug, SupportRequest, Question };

public enum Importance { Blocking, High, Medium, Low };

[Serializable]
class Declaration
{
    public string Type;
    public string Amount;
    public string Date;

    public static IForm<Declaration> BuildForm()
    {
        return new FormBuilder<Declaration>()
                .Message("Add a declaration")
                .Build();
    }
}

[Serializable]
class SupportRequest
{

    public SystemSelection? SystemSelection;
    public RequestType? RequestType;
    public Importance? Importance;

    public List<Declaration> Declarations;

    public static IForm<SupportRequest> BuildForm()
    {
        IForm<Declaration> aForm = new FormBuilder<Declaration>().Message("Add declaration").Build();

        // now what?

        return new FormBuilder<SupportRequest>()
                .Message("Welcome to the simple support bot!")
                .Build();
    }
}

Controller:

  [BotAuthentication]
  public class MessagesController : ApiController
{
    internal static IDialog<SupportRequest> MakeRootDialog()
    {
        // change something here??
        return Chain.From(() => FormDialog.FromForm(SupportRequest.BuildForm));
    }

    public async Task<Message> Post([FromBody]Message message)
    {
        if (message.Type == "Message")
        {
            return await Conversation.SendAsync(message, MakeRootDialog);
        }
        else
        {
            return HandleSystemMessage(message);
        }
    }

Upvotes: 1

Views: 1746

Answers (1)

Dmitri Soshnikov
Dmitri Soshnikov

Reputation: 727

You can compose your Dialogs using methods from Chain class. Since those methods also support LINQ syntax, you can write something like this in your MakeRootDialog to execute SupportRequest dialog and Decalaration dialog in sequence:

    internal static IDialog<SupportRequest> MakeRootDialog()
    {
        var dlg = from x in FormDialog.FromForm(SupportRequest.BuildForm)
                  from y in FormDialog.FromForm(Declaration.BuildForm)
                  select x;
        return dlg;
        // return Chain.From(() => FormDialog.FromForm(SupportRequest.BuildForm));
    }

You can also chain dialogs manually like this:

        var dlg = Chain.From(() => FormDialog.FromForm(SupportRequest.BuildForm))
            .ContinueWith<SupportRequest,Declaration>(async (ctx, sr) =>
            {
                var res = await sr;
                return FormDialog.FromForm(Declaration.BuildForm);
            });

Upvotes: 2

Related Questions