我们正在尝试在PrivateConversationData
的{{1}}中保存一个简单的可序列化对象,并从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);
}
}
}
,在MessagesController.cs中,我们只是调用
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);
}
在这种情况下,我们得到以下输出
await Conversation.SendAsync(activity, () => new DummyDialog()).ConfigureAwait(false);
var user = await StateHelper.GetUserAsync<BotUser>(activity);
System.Diagnostics.Debug.WriteLine("Within MC (end) >" + user?.UserId);
有什么问题吗?
答案 0 :(得分:1)
在加载对话框时,状态会随之加载,并且可以使用Context对象上的方法进行访问/保存。对话框完成后,状态将由SDK保留。如果您创建一个新的作用域,嵌套在对话框中,并尝试加载/保留状态:那么对话框状态将覆盖它。要解决此问题,可以在StateHelper中添加一个接受 IDialogContext 的方法,并在Dialog中使用该方法。