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