【发布时间】:2021-02-24 07:37:21
【问题描述】:
我正在使用 MS BotFramework v4。有一个 RootDialog 以 Dialog_A 或 Dialog_B 开头,具体取决于用户输入的内容。
TL;DR
如果在对话后开始新对话并且机器人未重新启动,则已分配值(不是初始值)的对话的私有变量不会重置为其初始值,从而导致意外的行为。如何避免这种情况?
详细
让我们假设以下场景: 这些对话框中的每一个都有一些私有变量来控制是输出长的还是短的介绍消息。仅应在第一次启动此对话框时输出长的。如果对话再次到达对话框,则只应打印短消息。
实现如下:
RootDialog.cs
public class RootDialog : ComponentDialog
{
private bool isLongWelcomeText = true;
// Some more private variables follow here
public RootDialog() : base("rootId") {
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[] {
WelcomeStep,
DoSomethingStep,
FinalStep
});
}
private async Task<DialogTurnContext> WelcomeStep(WaterfallStepContext ctx, CancellationToken token) {
if(isLongWelcomeText) {
await ctx.SendActivityAsync(MessageFactory.Text("A welcome message and some detailed bla bla about the bot"));
isLongWelcomeText = false;
} else {
await ctx.SendActivityAsync(MessageFactory.Text("A short message that hte bot is waiting for input"));
}
}
private async Task<DialogTurnContext> DoSomethingStep(WaterfallStepContext ctx, CancellationToken token) {
// call Dialog_A or Dialog_B depending on the users input
// Dialog X starts
await ctx.BeginDialogAsync("Dialog_X", null, token);
}
private async Task<DialogTurnContext> FinalStep(WaterfallStepContext ctx, CancellationToken token) {
// After dialog X has ended, RootDialog continues here and simply ends
await ctx.EndDialogAsync(null, token);
}
}
Dialog_A 和 Dialog_B 的结构相同。
问题
如果机器人处理了它的第一次对话,一切都会按预期进行(长欢迎文本会打印给用户,并且WelcomeStep 中的isLongWelcomeText 设置为false。然后当我开始新的对话时(新的conversationId和 userId)isLongWelcomeText 仍设置为 false,这会导致机器人在新对话中向新用户输出简短的欢迎文本。
在 BotFramework v3 中,对话框与所有变量值一起被序列化和反序列化。
如果我在 BF v4 中是对的,则不再序列化。
问题
如何解决这个问题?有没有更好的方法来做到这一点?
备注
我正在使用UserState 和ConversationState,它们在新对话中被序列化并重置。但我不想将每个对话框的每个私有变量值都存储在状态中。这不可能。
提前感谢
【问题讨论】:
-
我的回答可以接受吗?
标签: c# azure-storage chatbot botframework