Microsoft Bot Framework:例外:数据已更改

时间:2017-03-17 14:24:03

标签: botframework luis

我有一个机器人,有以下对话场景:

  1. 发送文本到LUIS
  2. LUIS意图调用context.Call(...)启动Dialog
  3. 此对话框终止,在userData中保存一些信息:

    private static async Task storeBotData(IDialogContext context, BotData userData) { Activity activity = (Activity)context.Activity; StateClient sc = activity.GetStateClient(); await sc.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData); }

    再次使用context.Call(...)再次调用另一个对话框。

  4. 然后最后一个对话框运行并终止。

  5. 我的问题是,在第一个对话框结束时更新用户数据(步骤3)时,我在Bot框架通道模拟器中有以下异常:

             `Exception: The data is changed [File of type 'text/plain']`...
    

    这里发生了什么?我认为当对话框终止时,它会自行调用setUserData,但我不明白为什么我无法在代码中的任何位置更新userData ...

    我试图捕获异常,但没有任何内容被捕获..但我知道userData已更新,因为当我尝试将其检索回来时,它会更新...

    欢迎任何帮助:)

    由于

2 个答案:

答案 0 :(得分:4)

Botframework在每次活动后恢复/保存对话状态,因此在典型流程中,典型流程如下所示:

[23:15:40] <- GET 200 getUserData 
[23:15:47] <- GET 200 getConversationData 
[23:15:47] <- GET 200 getPrivateConversationData 
...
[23:16:42] <- POST 200 setConversationData 
[23:16:42] <- POST 200 setUserData 
[23:16:42] <- POST 200 setPrivateConversationData 

正如前面提到的那样hereThese botData objects will fail to be stored if another instance of your bot has changed the object already.所以在你的情况下,当框架自己调用setUserData并且发现BotData已经被更改时(例如你的明确调用BotState.SetUserDataAsync)。我想这就是你无法捕捉异常的原因。

<强>解决方案: 我使用以下代码修复了问题:

private static void storeBotData(IDialogContext context, BotData userData)
{
        var data = context.UserData;
        data.SetValue("field_name", false);            
}

它起作用的原因是我们修改UserData的对象但允许botFramework自己“提交”它,所以没有冲突

答案 1 :(得分:1)

我同意@Artem(这也解决了我的问题,谢谢!)。我只想添加以下指南。

使用

var data = context.UserData;
data.SetValue("field_name", false);

只要有可用的IDialogContext对象,就让Bot Framework提交更改。

改为使用

StateClient sc = activity.GetStateClient();
await sc.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);

当您没有IDialogContext对象时,例如在MessageController类中。