从根对话框构建Formflow表单时传递数据的正确方法是什么? [英] What's the correct way to pass data when building a formflow form from a root dialog?

查看:155
本文介绍了从根对话框构建Formflow表单时传递数据的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using a root dialog in order to create a child formflow dialog, so that I can capture exceptions, etc.

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

I'm encountering an issue with passing a username value to the formflow dialog. Here's what I've tried..

[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),

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

I think this is wrong, because when I run the bot I get this exception...

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

Microsoft.Bot.Builder.Internals.Fibers.ClosureCaptureException: 'anonymous method closures that capture the environment are not serializable, consider removing environment capture or using a reflection serialization surrogate: CarValuationBot.Dialogs.RootDialog+<>c__DisplayClass1_0'

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

In the formflow dialog, here is how I'm using the username value..

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的调用才是问题所在.

Now, I did comment out the code which defines the field UserName, but I'm still getting the exception. That hints to me that it must be the call to BuildForm in the root dialog is the problem.

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

What is the best practise way of passing data to the formflow dialog in this scenario please?

推荐答案

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

I fgiured out that you can set the initial state of the dialog like so

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对话框通过构造函数存储用户名.

The formflow dialog then stores the username via the constructor..

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

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

   ....
}

这篇关于从根对话框构建Formflow表单时传递数据的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆