从根对话框构建Formflow表单时传递数据的正确方法是什么?

时间:2018-06-29 08:05:05

标签: botframework

我正在使用根对话框来创建子Formflow对话框,以便可以捕获异常等。

在将用户名值传递给Formflow对话框时遇到问题。这是我尝试过的。

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

        return Task.CompletedTask;
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
        var message = await result;

        var customerForm = new FormDialog<CarValuationDialog>(
            new CarValuationDialog(),
            () => CarValuationDialog.BuildForm(context.Activity?.From.Name),
            FormOptions.PromptInStart);

        context.Call(customerForm, FormSubmitted);        
    }

    ....
}

关键是

() => CarValuationDialog.BuildForm(context.Activity?.From.Name),

我认为这是错误的,因为当我运行机器人时,我会收到此异常...

  

Microsoft.Bot.Builder.Internals.Fibers.ClosureCaptureException:'捕获环境的匿名方法闭包不可序列化,请考虑删除环境捕获或使用反射序列化代理:CarValuationBot.Dialogs.RootDialog + <> c__DisplayClass1_0'

在Formflow对话框中,这是我使用用户名值的方式。

public static IForm<CarValuationDialog> BuildForm(string userName)
{
    var builder = new FormBuilder<CarValuationDialog>();

    return builder
        .Field(new FieldReflector<CarValuationDialog>(nameof(UserName))
            .SetDefine(async (state, field) =>
                {
                    field.SetValue(state, userName);

                    return await Task.FromResult(true);
                })
        .SetActive(state => string.IsNullOrEmpty(state.UserName)))


        ... rest of code
}

现在,我确实注释掉了定义字段UserName的代码,但是我仍然遇到异常。这提示我,问题一定是在根对话框中对BuildForm的调用。

在这种情况下,将数据传递到表单流对话框的最佳实践方法是什么?

1 个答案:

答案 0 :(得分:1)

我认为您可以像这样设置对话框的初始状态

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
    var message = await result;

    string userName = "Jason";
    //string userName = context.Activity?.From.Name;

    var customerForm = new FormDialog<CarValuationDialog>(
        new CarValuationDialog(userName),
        () => CarValuationDialog.BuildForm(),
        FormOptions.PromptInStart);

    context.Call(customerForm, FormSubmitted);   
}

然后,formflow对话框通过构造函数存储用户名。

public class CarValuationDialog : IDialog<CarValuationDialog>
{
    public string UserName { get; set; 

    public CarValuationDialog(string userName)
    {
        UserName = userName;
    }

   ....
}