我正在使用根对话框来创建子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
的调用。
在这种情况下,将数据传递到表单流对话框的最佳实践方法是什么?
答案 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;
}
....
}