BotFramework:PrivateConversationData 或 UserData 变空
BotFramework: PrivateConversationData or UserData becomes empty
在MessagesController.cs
中,下面的代码在Post
方法中执行,
if (activity.Text.ToLowerInvariant().StartsWith("code:"))
{
var stateClient = activity.GetStateClient();
var botData = await stateClient.BotState.GetUserDataAsync(activity.ChannelId, activity.From.Id);
var token = botData.GetProperty<string>("AccessToken");
BotUserModel botUser = CreateNewUser(token);
var privateData = await stateClient.BotState.GetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id);
privateData.SetProperty<BotUserModel>("botUser", botUser);
}
else
{
await Conversation.SendAsync(activity, () => new LuisDialog());
}
这是将 botUser 保存到 PrivateConversationData 字典
在 LUIS 对话框中,
[LuisIntent("DoSomething")]
public async Task DoSomething(IDialogContext context, LuisResult result)
{
BotUserModel botUser;
context.PrivateConversationData.TryGetValue<BotUserModel>("botUser", out botUser);
// Just to test
context.PrivateConversationData.SetValue<BotUserModel>("TestValue", new BotUserModel());
}
在这里,我遇到了一个异常 KeyNotFoundException:botUser
BotUserModel 被标记为 [Serializable]
并且几乎没有 public 属性 - 全部带有 get/set。我检查了 IBotBag(即 PrivateConversationData)及其空
[LuisIntent("DoSomethingNew")]
public async Task DoSomethingNew(IDialogContext context, LuisResult result)
{
// Assuming DoSomething intent is invoked first
BotUserModel botUser;
context.PrivateConversationData.TryGetValue<BotUserModel>("TestValue", out botUser);
// Here, no exception!
}
现在,我在 DoSomething
方法中获取 LUIS 对话框中设置的 TestValue 值。
因此,从本质上讲,其他 LUIS 意图可以访问 LUIS Intent 中 PrivateConversationData 或 UserData 的任何数据集;而 MessageController.cs 中的数据集(在调用 LUIS 之前)在 LUIS 中不可访问。
也尝试过 UserData
。
我错过了什么吗?
您忘记将私有数据存储设置回状态客户端。这应该可以正常工作。
var privateData = await stateClient.BotState.GetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id);
privateData.SetProperty<BotUserModel>("botUser", botUser);
await stateClient.BotState.SetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id, privateData);
查看状态客户端上的documentation。
在MessagesController.cs
中,下面的代码在Post
方法中执行,
if (activity.Text.ToLowerInvariant().StartsWith("code:"))
{
var stateClient = activity.GetStateClient();
var botData = await stateClient.BotState.GetUserDataAsync(activity.ChannelId, activity.From.Id);
var token = botData.GetProperty<string>("AccessToken");
BotUserModel botUser = CreateNewUser(token);
var privateData = await stateClient.BotState.GetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id);
privateData.SetProperty<BotUserModel>("botUser", botUser);
}
else
{
await Conversation.SendAsync(activity, () => new LuisDialog());
}
这是将 botUser 保存到 PrivateConversationData 字典
在 LUIS 对话框中,
[LuisIntent("DoSomething")]
public async Task DoSomething(IDialogContext context, LuisResult result)
{
BotUserModel botUser;
context.PrivateConversationData.TryGetValue<BotUserModel>("botUser", out botUser);
// Just to test
context.PrivateConversationData.SetValue<BotUserModel>("TestValue", new BotUserModel());
}
在这里,我遇到了一个异常 KeyNotFoundException:botUser
BotUserModel 被标记为 [Serializable]
并且几乎没有 public 属性 - 全部带有 get/set。我检查了 IBotBag(即 PrivateConversationData)及其空
[LuisIntent("DoSomethingNew")]
public async Task DoSomethingNew(IDialogContext context, LuisResult result)
{
// Assuming DoSomething intent is invoked first
BotUserModel botUser;
context.PrivateConversationData.TryGetValue<BotUserModel>("TestValue", out botUser);
// Here, no exception!
}
现在,我在 DoSomething
方法中获取 LUIS 对话框中设置的 TestValue 值。
因此,从本质上讲,其他 LUIS 意图可以访问 LUIS Intent 中 PrivateConversationData 或 UserData 的任何数据集;而 MessageController.cs 中的数据集(在调用 LUIS 之前)在 LUIS 中不可访问。
也尝试过 UserData
。
我错过了什么吗?
您忘记将私有数据存储设置回状态客户端。这应该可以正常工作。
var privateData = await stateClient.BotState.GetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id);
privateData.SetProperty<BotUserModel>("botUser", botUser);
await stateClient.BotState.SetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id, privateData);
查看状态客户端上的documentation。