将访问器传递到 WaterfallDialog 会在第一步 Bot Framework v4 后导致错误
Passing Accessors into WaterfallDialog causes error after first step Bot Framework v4
当我将 BotAccessors
从主对话框传递到另一个对话框时遇到问题。我有动力发送访问器,因为我需要从任何对话框访问并保存 UserProfile
中的状态。
这就是我传递它的方式:
await dialogContext.BeginDialogAsync(SiteReviewDialog.id, _accessors, cancellationToken: cancellationToken);
SiteReviewDialog
第一步运行良好并提示用户,但在进入第二步之前就出错了(断点未命中)。
我尝试删除 SiteReviewDialog
中对 accessors
的所有引用,看来解决此问题的唯一方法是根本不传递 accessors
。如果我通过 accessors
,我得到的错误是:http://freetexthost.com/sdgdilpyxv
从错误来看,第232行在我的OnTurnAsync
内:
var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
我试图从第一个 AddStep(async (stepContext, cancellationToken)
开始跟踪 SiteReviewDialog
中的代码执行,它逐行退出然后点击 OnTurnAsync
并到达第 232 行然后出错。有人有什么建议吗?
首先解释一下发生了什么:您将 _accessors
传递给的参数是为对话框的 "options" 对象保留的。这类似于设置对话框的行为方式。例如,在提示的情况下,这始终是 PromptOptions
subclass。这些选项对象在对话框的执行生命周期内被序列化并存储在堆栈中,因此您在传递 _accessors
时遇到异常的原因是因为它包含不可序列化的类型。所以,长话短说,您不希望以这种方式传递访问器。
访问器实际上是单例,您要做的是通过对话框的构造函数链传递它们。所以你会把 IStatePropertyAccessor<T>
(或者 "accessors" class 如果你决定遵循那个模式)到你的 SiteReviewDialog
构造函数然后确保将它传递给任何它通过构造函数创建的子对话框。注意:对话框本身也应该真正创建为单例。
从那里开始,只需要在需要时使用访问器,因为您总是给它一个 ITurnContext
它应该从中加载数据,并且单例实例使用特定于该上下文的标识符来确保加载了正确的数据。
当我将 BotAccessors
从主对话框传递到另一个对话框时遇到问题。我有动力发送访问器,因为我需要从任何对话框访问并保存 UserProfile
中的状态。
这就是我传递它的方式:
await dialogContext.BeginDialogAsync(SiteReviewDialog.id, _accessors, cancellationToken: cancellationToken);
SiteReviewDialog
第一步运行良好并提示用户,但在进入第二步之前就出错了(断点未命中)。
我尝试删除 SiteReviewDialog
中对 accessors
的所有引用,看来解决此问题的唯一方法是根本不传递 accessors
。如果我通过 accessors
,我得到的错误是:http://freetexthost.com/sdgdilpyxv
从错误来看,第232行在我的OnTurnAsync
内:
var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
我试图从第一个 AddStep(async (stepContext, cancellationToken)
开始跟踪 SiteReviewDialog
中的代码执行,它逐行退出然后点击 OnTurnAsync
并到达第 232 行然后出错。有人有什么建议吗?
首先解释一下发生了什么:您将 _accessors
传递给的参数是为对话框的 "options" 对象保留的。这类似于设置对话框的行为方式。例如,在提示的情况下,这始终是 PromptOptions
subclass。这些选项对象在对话框的执行生命周期内被序列化并存储在堆栈中,因此您在传递 _accessors
时遇到异常的原因是因为它包含不可序列化的类型。所以,长话短说,您不希望以这种方式传递访问器。
访问器实际上是单例,您要做的是通过对话框的构造函数链传递它们。所以你会把 IStatePropertyAccessor<T>
(或者 "accessors" class 如果你决定遵循那个模式)到你的 SiteReviewDialog
构造函数然后确保将它传递给任何它通过构造函数创建的子对话框。注意:对话框本身也应该真正创建为单例。
从那里开始,只需要在需要时使用访问器,因为您总是给它一个 ITurnContext
它应该从中加载数据,并且单例实例使用特定于该上下文的标识符来确保加载了正确的数据。