GeekzSG
GeekzSG

Reputation: 973

BotFramework: PrivateConversationData or UserData becomes empty

In MessagesController.cs, following code is executed in Post method,

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());
}

This is saving botUser into PrivateConversationData dictionary

Inside the LUIS Dialog,

[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());
}

Here, I'm getting an exception KeyNotFoundException:botUser

BotUserModel is marked [Serializable] and has few public properties - all with get/set. I checked the IBotBag (i.e. PrivateConversationData) and its empty

 [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!
 }

Now, here I get the value of TestValue set in LUIS Dialog in DoSomething method.

So essentially, any data set to PrivateConversationData or UserData inside LUIS Intent is accessible by other LUIS intents; whereas, data set in MessageController.cs (before LUIS is called) is not accessible within LUIS.

Tried with UserData as well.

Am I missing anything?

Upvotes: 0

Views: 597

Answers (1)

Xeno-D
Xeno-D

Reputation: 2213

You are forgetting to set the private data store back into the state client. This should make it work.

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);

Check out the documentation on the state client.

Upvotes: 1

Related Questions