我们试图在PrivateConversationData中将一个简单的可序列化对象保存在Dialog中,并从MessagesController中的状态访问它。
由于某些原因,在对话框中执行Context.Done之后,我们将不会返回存储在状态中的数据。
public static async Task SetUserAsync<T>(IActivity activity, T botUser) where T : IBotUser
{
if (botUser != null)
{
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity.AsMessageActivity()))
{
var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
var key = new AddressKey()
{
BotId = activity.Recipient.Id,
ChannelId = activity.ChannelId,
UserId = activity.From.Id,
ConversationId = activity.Conversation.Id,
ServiceUrl = activity.ServiceUrl
};
var privateData = await botDataStore.LoadAsync(key, BotStoreType.BotPrivateConversationData, CancellationToken.None);
privateData.SetProperty<T>(Keys.CacheBotUserKey, botUser);
await botDataStore.SaveAsync(key, BotStoreType.BotPrivateConversationData, privateData, CancellationToken.None);
await botDataStore.FlushAsync(key, CancellationToken.None);
}
}
}对话框代码非常简单,如
public override async Task ProcessMessageAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
BotUser user = new BotUser { UserId = "user1" };
await StateHelper.SetUserAsync(context.Activity, user);
var userFromState = await StateHelper.GetUserAsync<BotUser>(context.Activity);
Debug.WriteLine("Within dialog (after set) >" + userFromState?.UserId);
context.Done<object>(null);
}在MessagesController.cs中,我们只是简单地调用
await Conversation.SendAsync(activity, () => new DummyDialog()).ConfigureAwait(false);
var user = await StateHelper.GetUserAsync<BotUser>(activity);
System.Diagnostics.Debug.WriteLine("Within MC (end) >" + user?.UserId);在这种情况下,我们得到的输出低于
Within dialog (after set) > user1
Within MC (end) >有什么不对劲吗?
发布于 2018-06-21 21:11:51
当一个对话框加载时,状态将被加载,并且可以通过使用上下文对象上的方法来访问/保存状态。当对话框完成时,SDK将持久化状态。如果您创建一个嵌套在对话框中的新作用域,并尝试加载/持久化状态:那么对话框状态将覆盖它。要解决这个问题,您可以添加一个接受IDialogContext,的StateHelper方法,并在对话框中使用该方法。
https://stackoverflow.com/questions/50939793
复制相似问题