我在Bot Framework上工作了几天,真是太新了。我一直在试图了解管理国家的情况,说实话我只是不明白。似乎最近的框架和建议已经发生了很大变化,似乎没有明确的建议或示例。
此page说:
将信息保存为机器人状态。这将需要您设计 您的对话框可以访问机器人的状态属性访问器。
但是没有实现此目的的示例。
“瀑布”对话框之一的最后一步如下所示:
AddStep(async (stepContext, cancellationToken) =>
{
var response = stepContext.Result as FoundChoice;
stepContext.Values["maxPrice"] = response;
return await stepContext.BeginDialogAsync(SearchDialog.Id, null, cancellationToken);
});
这基本上是一个新对话框的开始,我想通过将该对象从该对话框中收集的数据传递到SearchDialog
中,或者最好将其保存到我的BotAccessors
中,然后SearchDialog
检索并使用它。
所有MS示例的瀑布步骤都定义为async
类上的IBot
方法。他们也不建议将bot对话框放在一起,使该示例变得毫无用处。
此外,似乎甚至Microsoft v4文档也已经过时,例如this doc,这仍然告诉我们使用不推荐使用的代码,例如:
options.State.Add(new ConversationState(storage));
不幸的是,目前看来,文档对这个主题的帮助比实际更令人困惑。管理此状态的最佳方法是什么?
答案 0 :(得分:2)
看看在samples repo或creating a basic bot中从Azure模板中设置基本漫游器的方式。
状态属性访问器在BasicBot
类中声明:
private readonly IStatePropertyAccessor<GreetingState> _greetingStateAccessor;
然后将其分配到BasicBot
constructor:
_greetingStateAccessor = _userState.CreateProperty<GreetingState>(nameof(GreetingState));
然后它是passed到GreetingDialog
构造函数:
Dialogs.Add(new GreetingDialog(_greetingStateAccessor, loggerFactory));
然后将其分配给GreetingDialog
类的属性:
UserProfileAccessor = userProfileStateAccessor ?? throw new ArgumentNullException(nameof(userProfileStateAccessor));
然后在整个GreetingDialog
类中使用GetAsync
和SetAsync
方法在许多地方使用它。例如:
var greetingState = await UserProfileAccessor.GetAsync(stepContext.Context, () => null);
答案 1 :(得分:1)
“瀑布对话框”的最后两个步骤可能类似于以下内容:
public async Task<DialogTurnResult> AskForLocation(WaterfallStepContext sc, CancellationToken cancellationToken)
{
// the previous step asked for the Email so now bot is going to save it in botstate
_state = await _accessor.GetAsync(sc.Context, () => new MyApplicationState());
var email = _state.Email = (string)sc.Result;
// this is not in the template because it is saving in a different manner
// just being explicit about saving here
await _accessor.SetAsync(sc.Context, _state);
await sc.Context.SendActivityAsync("Got your email!");
var prompt = new PromptOptions
{
Prompt = MessageFactory.Text($"Please specify location."),
};
return await stepContext.PromptAsync(locationPrompt, prompt);
}
public async Task<DialogTurnResult> FinishDialog(WaterfallStepContext sc, CancellationToken cancellationToken)
{
_state = await _accessor.GetAsync(sc.Context);
_state.Location = (string)sc.Result;
// save location this time
await _accessor.SetAsync(sc.Context, _state);
await sc.Context.SendActivityAsync("Got your location!");
return await sc.EndDialogAsync();
}
如果退出上面的对话框,并假设您实现了StateBotAccessors并且正在使用UserProfile属性,则可以通过以下方式检索它:
var _state = await stateBotAccessors.UserState.UserProfileAccessor.GetAsync(context);
或者,如果您想从子对话框中传递它,则可以以:
结尾 return await sc.EndDialogAsync(_state);