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