首页 > 解决方案 > 在第一步 Bot Framework v4 之后将访问器传递给 WaterfallDialog 会导致错误

问题描述

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 行,然后出现错误。有没有人有什么建议?

标签: c#.netdialogbotframeworkstate-management

解决方案


首先解释发生了什么:您传递_accessors给的参数是为对话框的“选项”对象保留的。这类似于对话框应该如何表现的设置。例如,在提示的情况下,这始终是一个PromptOptions子类。这些选项对象在对话框的执行生命周期内被序列化并存储在堆栈中,因此您收到异常传递的原因_accessors是因为它包含不可序列化的类型。所以,长话短说,你不想以这种方式传递你的访问者。

访问器实际上是单例,您想要做的是通过对话框的构造函数链传递它们。因此,您将IStatePropertyAccessor<T>(或“访问器”类,如果您决定遵循该模式)带到您的SiteReviewDialog构造函数,然后确保将其传递给它通过其构造函数创建的任何子对话框。注意:对话框本身也应该创建为单例。

从那里开始,只需在需要时使用访问器,因为您总是给它一个ITurnContext应该从中加载其数据的访问器,并且单例实例使用特定于该上下文的标识符来确保加载正确的数据。


推荐阅读