我正在使用Bot Builder 3.8.5。
在Microsoft Bot Framework文档here上指定:
默认情况下,Bot Framework SDK for .NET使用。来存储状态数据 Bot Framework State服务,仅用于原型设计 并且不适合生产环境中的机器人使用。对于 您在生产环境中的性能和安全性原因 应该使用Bot Builder SDK Azure Extensions来存储状态 您自己的Azure表存储或Azure DocumentDB存储中的数据 创建IBotDataStore的自定义实现来存储状态数据 您指定的目的地。
我决定将Bot构建器扩展与Azure Table存储一起使用。状态正确保存到表存储中。
但是,我有以下问题:
在MessageController.cs
我正在添加私人对话数据字符串,如下所示(因为我无法访问IDialogContext
):
StateClient stateClient = activity.GetStateClient();
BotData userData = await stateClient.BotState.GetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id);
userData.SetProperty<string>("MyKey", "MyValue");
await stateClient.BotState.SetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id, userData);
然后在我的RootDialog文件中,我试图通过以下方式提取这些数据:
context.PrivateConversationData.TryGetValue("MyKey", out myValue);
但context.PrivateConversationData不包含此键,它始终返回null。
注意:当我使用默认的Bot State服务时,它完全正常工作......
如果我使用以下代码,它可以工作,但它对性能有重大影响(检索botdata的调用非常慢):
var stateClient = context.Activity.GetStateClient();
BotData pConversationData = context.Activity.GetStateClient().BotState.GetPrivateConversationDataAsync( context.Activity.ChannelId, context.Activity.Conversation.Id, context.Activity.From.Id).GetAwaiter().GetResult();
return pConversationData.GetProperty<T>("MyKey");
我做错了什么?
更新
似乎覆盖IBotDataStore(使用bot构建器扩展)适用于context.UserData但不适用于StateClient.BotState ......事实上,我认为我需要为IBotState提供自定义实现才能够访问IDialog之外的BotState ..
答案 0 :(得分:2)
我想我找到了克服这个问题的方法。问题是如果你想在IDialog之外访问Bot状态,你就无法访问正在处理bot状态的加载/保存/刷新的IDialogContext和context.PrivateConversationData或context.UserData。
如果您使用的是默认的bot状态服务,但是当您拥有自定义的IBotDataStore(如bot框架文档中所推荐的那样)时,可以使用StateClient,您不能使用默认的StateClient,因为它仍然指向默认的状态服务。我想一个解决方案可能是创建自定义IStateClient / IBotState。
而不是那样,我在MessageController中使用了以下代码:
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(default(CancellationToken));
botData.PrivateConversationData.SetValue<T>("MyKey", value);
await botData.FlushAsync(default(CancellationToken));
}
使用此代码,我能够在自定义IBotDataStore中保存/加载数据。
希望这有帮助!
答案 1 :(得分:1)
在此处设置userData值时:
StateClient stateClient = activity.GetStateClient();
BotData userData = await stateClient.BotState.GetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id);
userData.SetProperty<string>("MyKey", "MyValue");
添加以下内容以强制更新数据:
await stateClient.BotState.SetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id, userData);
然后它应该正确存储和访问