【问题标题】:How can I access Bot Framework ConversationData outside of a dialog like in messages controller?如何在消息控制器中的对话框之外访问 Bot Framework ConversationData?
【发布时间】:2018-02-15 13:23:59
【问题描述】:

在我的机器人中的一个对话框中,我在 ConversationData 中存储了一个标志值,如下所示:

context.ConversationData.SetValue("SomeFlag", true);

稍后,我需要在 MessagesController 中检查该标志,消息被分派到对话框之前。根据this previous question,我尝试通过 StateClient 检索 ConversationData,如下所示:

public async Task<HttpResponseMessage> Post([FromBody] Activity incomingMessage)
{
    StateClient stateClient = incomingMessage.GetStateClient();
    BotData userData = await stateClient.BotState.GetConversationDataAsync(message.ChannelId, message.Conversation.Id);
    bool finishedQuote = userData.GetProperty<bool>("SomeFlag");
    //...
    // do conditional logic, then dispatch to a dialog as normal
}

但是,在运行时,userData 变量包含一个 BotData 对象,其中userData.Data 为空,我无法通过GetProperty 检索任何存储的标志。我在relevant documentation 中没有看到任何有助于阐明这个问题的内容——我在这里可能做错了什么?我有什么误解吗?

【问题讨论】:

    标签: c# botframework


    【解决方案1】:

    以下内容应该可以满足您的需要:

    if (activity.Type == ActivityTypes.Message)
    {
    
        var message = activity as IMessageActivity;
        using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
        {
            var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
            var key = Address.FromActivity(message);
    
            ConversationReference r = new ConversationReference();
            var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);
    
            //you can get/set UserData, ConversationData, or PrivateConversationData like below
            //set state data
            userData.SetProperty("key 1", "value1");
            userData.SetProperty("key 2", "value2");
            //get state data
            userData.GetProperty<string>("key 1");
            userData.GetProperty<string>("key 2");
    
            await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
            await botDataStore.FlushAsync(key, CancellationToken.None);
        }
        await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
    }
    

    【讨论】:

    • 谢谢,这太完美了!只需将其更改为加载 ConversationData 而不是 UserData 就可以满足我的需要!
    【解决方案2】:

    使用 StateClient 初始化 BotState 对象,如下所示。试试下面的代码

       public static T GetStateData<T>(Activity activity, string key)
        {
            BotState botState = new BotState(activity.GetStateClient());
            BotData botData = botState.GetConversationData(activity.ChannelId, activity.Conversation.Id);
            return botData.GetProperty<T>(key);
        }
    

    【讨论】:

    • 这不起作用 - 它导致与我的问题中发布的 sn-p 相同的结果。
    • 测试它尝试将“activity.ChannelId”编码为“webchat”,并在保存和检索时为对话提供任何固定值。保存在 ConversationData 中的任何具体原因?你也可以试试 UserData、PrivateConversationData 等
    • 我没有使用网络聊天,我使用的是 Bot Framework Emulator - 而且我认为加载 UserData 或 PrivateConversationData 不会有任何不同,因为它们的加载方式相同。我很欣赏这种尝试,但上面 JasonSowers 接受的解决方案效果很好。
    • activity.GetStateClient() 已弃用。它将检索默认状态客户端,仅用于原型设计:blog.botframework.com/2017/07/18/saving-state-azure-extensions
    猜你喜欢
    • 2019-10-16
    • 2016-08-21
    • 2021-03-11
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 2019-07-20
    相关资源
    最近更新 更多