2017-03-17 61 views
2

我有以下的對話場景中殭屍:微軟機器人框架:異常:在更改數據

  1. 發送短信給LUIS
  2. LUIS意圖電話context.Call(...)推出一個對話框
  3. 此對話框終止時,保存在用戶數據的一些信息:

    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. 然後最後一個對話框運行並終止。

我的問題是,在第一個對話框的最終更新用戶數據(步驟3)的時候,我在博特框架通道仿真器以下異常:

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

什麼在這裏發生?我認爲當一個對話終止時,它自己調用setUserData,但我不明白爲什麼我不能在代碼中的任何地方更新userData ...

我試圖捕捉異常,但沒有任何捕獲..但我知道,用戶數據被更新,因爲當我嘗試找回它回來了,它被更新......

歡迎任何幫助:)

感謝

+0

您正在使用哪個版本的框架? – Artem

回答

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「落實」它自己,所以沒有衝突

+0

謝謝@Artem,它完美的工作。您的權利,最好是將「提交」部分留給framewrok本身。 +1 – Ynnad

1

我同意@Artem(這也解決了我的問題,謝謝!)。我只想添加以下指南。

使用

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

,只要你有一個IDialogContext對象,所以你讓機器人框架提交更改。

改用

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

當你沒有一個IDialogContext對象,例如在MessageController類中。