从Bot Framework中的另一个表单调用表单

时间:2018-01-18 13:05:36

标签: c# botframework

我希望根据第一种形式输入的条件设置从另一种形式调用一个表单。当我尝试这个代码时,我的第二种形式从开始一次又一次地反复出现而不是移动到下一个字段。

  public static IForm<Form1> BuildForm()
    {
        return new FormBuilder<Form1>()
            .Message("Insert following details")
            .Field(nameof(Operation))
            .OnCompletion(CallOperationDialog)
            .Message($"Thank you")
            .Build();
    }

    private static async Task CallOperationDialog(IDialogContext context, Form1state)
    {
        if (condition1)
        {               
            await context.Forward(Chain.From(() => FormDialog.FromForm(Form2)), ResumeAfterForm2, context.Activity.AsMessageActivity(), CancellationToken.None);
        }
    }

如果我将第二个表单保存在具有相同类型的Form1的同一个类中,那么它将继续加载循环。

当我在单独的文件中使用它时,它说它期待Form2但得到Form1。我怎样才能从另一个表格中拨打一个表格,因为我想保持一个有导向的对话?

1 个答案:

答案 0 :(得分:2)

我在第一个表单流对话框的context.Wait方法中设置ResumeAfter时重现了您的问题。这将使第二个对话框在用户设置表单流对话框2的第一个字段时结束。由于您没有发布所有代码,我认为这是问题所在。

然后要解决这个问题,我们需要等待整个表单流对话框的结果,而不是等待表格流对话框的第一个字段,意味着我们需要正确使用context.Wait方法,不要等待使用输入如果你想在第一个表单流对话框的ResumeAfter方法中调用第二个表单流。

我将从RootDialog这里调用第一个和第二个对话框作为示例,如果您想将第一个表单流对话框用作根对话框,那么它就是类似的情况。

我的两个FormFlow对话框是这样的:

[Serializable]
public class FFDialog1
{
    public string Test { get; set; }
    public string Description { get; set; }
    public static IForm<FFDialog1> BuildForm()
    {
        return new FormBuilder<FFDialog1>()
            .Message("Welcome to the first FormFlow dialog")
            .Field(nameof(Test))
            .Field(nameof(Description))
            .Build();
    }
}

public enum YesOrNo
{
    Yes,
    No
}

[Serializable]
public class FFDialog2
{
    public YesOrNo? Confirmation;
    public string Input { get; set; }
    public static IForm<FFDialog2> BuildForm()
    {
        return new FormBuilder<FFDialog2>()
            .Message("Welcome to the second FormFlow dialog")
            .Field(nameof(Confirmation))
            .Field(nameof(Input))
            .Build();
    }
}

RootDialog中,我称之为:

[Serializable]
public class RootDialog : IDialog<object>
{
    public Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);

        return Task.CompletedTask;
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    {
        var activity = await result as Activity;

        //call the first formflow dialog
        var form = new FormDialog<FFDialog1>(new FFDialog1(), FFDialog1.BuildForm, FormOptions.PromptInStart, null);
        context.Call(form, ResumeAfterFirstFFDialog);
    }

    private async Task ResumeAfterFirstFFDialog(IDialogContext context, IAwaitable<object> result)
    {
        var dialog = await result as FFDialog1;

        //call the second formflow dialog according to the result of first one.
        if (dialog.Test != null && dialog.Description != null)
        {
            var form = new FormDialog<FFDialog2>(new FFDialog2(), FFDialog2.BuildForm, FormOptions.PromptInStart, null);
            context.Call(form, ResumeAfterSecondFFDialog);
        }
    }

    private async Task ResumeAfterSecondFFDialog(IDialogContext context, IAwaitable<object> result)
    {
        //get result of formflow dialog 2.
        var dialog = await result as FFDialog2;

        await context.PostAsync("Work is done!");

        context.Wait(MessageReceivedAsync);
    }
}

此处我没有设置第一个表单流对话框的OnCompletion,因为在调用ResumeAfterFirstFFDialog时会提交结果,在此方法中调用第二个结果是相同的。