2017-07-13 8 views
0

私はBot Builder 3.8.5を使用しています。ボットフレームワークSDKのみ をプロトタイピングするためのものとされている ボットフレームワーク状態サービスを使用して、.NETを格納状態データのために、デフォルトではカスタムIBotDataStoreはcontext.PrivateConversationDataを破損します

:マイクロソフトボットFrameworkのドキュメントhereに指定されているように

プロダクション環境でボットが使用するようには設計されていません。本番環境での パフォーマンスとセキュリティ上の理由から、あなた べきいずれかの状態データを保存するためにIBotDataStoreのカスタム実装を作成し、独自のAzureテーブルストレージまたはAzureのDocumentDBストアまたは 状態に データを保存するためにボットビルダーSDK Azureの拡張機能を使用します 指定する宛先。

私は、Azure TableストレージでBotビルダー拡張を使用することに決めました。状態はテーブルストレージに正しく保存されます。その後で

StateClient stateClient = activity.GetStateClient(); 
BotData userData = await stateClient.BotState.GetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id); 
userData.SetProperty<string>("MyKey", "MyValue"); 
await stateClient.BotState.SetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id, userData); 

MessageController.cs

(私はIDialogContextへのアクセスを持っていないとして)私は以下のようにプライベートな会話データ列を追加してい:

しかし、私は次の問題を持っています私RootDialogの私は以下のことで、このデータを抽出しようとしていますファイル:

context.PrivateConversationData.TryGetValue("MyKey", out myValue); 

しかしcontext.PrivateConversationDataが、それこのキーが含まれていませんlwaysはnullを返します。

注:私は、デフォルトのボット状態サービスを使用していたとき、それは完璧に働いていた...

私は、次のコードを使用している場合、それは動作しますが、それは、パフォーマンスに大きな影響を持っている(呼び出しがbotdataを取得することです非常に遅い):

私は間違っていますか?

UPDATE

それは(ボットビルダー拡張子を持つ)IBotDataStoreをオーバーライドすることはcontext.UserDataのためではなく、StateClient.BotStateのために働くようだ...実際に、私は私が習慣を持っている必要があると思いますIBotStateの実装すぎIDialogの外BotStateにアクセスできるようにする。..

+0

私はここで同様の問題に答えていました:https://stackoverflow.com/questions/42860020/microsoft-bot-framework-exception-the-data-is-changed/42913460#42913460 – Artem

+0

@Artem私は本当に使用したいと思いますcontext.UserDataまたはcontext.PrivateConversationDataを呼び出し、フレームワークにコミットさせます。しかし、メッセージコントローラーでは、IDialogContextの権利にアクセスできません。 – ben

+0

@Artemさらに、私はこれらのコード行を使用すると:var stateClient = context.Activity.GetStateClient(); BotData pConversationData = context.Activity.GetStateClient()。BotState.GetPrivateConvers ationDataAsync(context.Activity.ChannelId、context.Activity.Conversation.Id、context.Activity.From.Id).GetAwaiter()。GetResult();戻り値pConversationData.GetProperty ( "MyKey");私は私の鍵の価値を得ることができるので、これは並行性の問題ではないと思う。 – ben

答えて

1

しなければならない

await stateClient.BotState.SetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id, userData); 

は、それから私は、私はこの問題を克服する方法を見つけたと思います。問題は、IDialog外のBot状態にアクセスしたい場合、ボット状態のロード/保存/フラッシュを処理しているIDialogContextとcontext.PrivateConversationDataまたはcontext.UserDataへのアクセス権を持っていないことです。

デフォルトのボット状態サービスを使用していても、ボットフレームワークのドキュメントで推奨されているようにカスタムのIBotDataStoreを使用している場合、StateClientを使用することはできますが、デフォルトのStateClientは、サービス。私は1つの解決策がカスタムIStateClient/IBotStateを作成することができると思います。その代わりの

は、私は私のMessageControllerに次のコードを使用:

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity)) 
{ 
     var botData = scope.Resolve<IBotData>(); 
     await botData.LoadAsync(default(CancellationToken)); 
     botData.PrivateConversationData.SetValue<T>("MyKey", value); 
     await botData.FlushAsync(default(CancellationToken)); 
} 

をこのコードでは、私は私のカスタムIBotDataStore中/ロード・データを保存することができました。

希望すると便利です。

1

ここにあなたのuserdata値を設定:

StateClient stateClient = activity.GetStateClient(); 
BotData userData = await stateClient.BotState.GetPrivateConversationDataAsync(activity.ChannelId, activity.Conversation.Id, activity.From.Id); 
userData.SetProperty<string>("MyKey", "MyValue"); 

UPDするデータを強制的に次の行を追加します。 ated:それは正しく保存され、アクセス可能

+0

謝罪、私は元の質問にこのコード行を追加するのを忘れてしまった。しかし残念ながら、私はすでにそれをやっています...それでもデフォルトのボット状態サービスでは動作しますが、カスタムテーブルデータストアでは機能しません。 (元の質問に行を追加する) – ben

+0

遅延の問題か他に何かありますか?あなたは数秒後にこの値を取得しようとしますか?あなたのストレージを見て、値が追加されたときにチェックできますか? –

+0

私はちょうど待ってみましたが、何も...これは奇妙です..デフォルトボット状態サービスとうまく動作しています..コンテキストを厳密に同一に検索/設定する2つの方法はありますか? – ben

関連する問題