我正在尝试使用嵌套对话框构建聊天机器人,该对话框应该从用户那里收集信息并将其存储在Azure CosmosDB中。在我实现Cosmos DB存储之前,该对话框运行良好。现在,使用CosmosDB存储,对话框将在第一个对话框中的第一个任务上循环,而不是继续。我该如何解决这个问题?
从对话框开始,以及在实现CosmosDB存储之前的状态。我基本上遵循了此示例43.complex-dialog中的代码。
然后,实现存储,我以this answer为指导。我像这样在Startup.cs中设置cosmosDB存储:
public class Startup
{
private const string CosmosServiceEndpoint = "MyCosmosServiceEndpoint";
private const string CosmosDBKey = "MyCosmosDBKey";
private const string CosmosDBDatabaseName = "MyCosmosDBDatabaseName";
private const string CosmosDBCollectionName = "MyCosmosDBCollectionName";
private const string CosmosDBPartitionKey = "MyCosmosDBPartitionKey";
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
var storage = new CosmosDbStorage(new CosmosDbStorageOptions
{
AuthKey = CosmosDBKey,
CollectionId = CosmosDBCollectionName,
CosmosDBEndpoint = new Uri(CosmosServiceEndpoint),
DatabaseId = CosmosDBDatabaseName,
PartitionKey = CosmosDBPartitionKey
});
var conversationState = new ConversationState(storage);
var userState = new UserState(storage);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
services.AddSingleton<MainDialog>();
services.AddTransient<IBot, WelcomeBot<MainDialog>>();
services.AddSingleton<IStorage, MemoryStorage>();
services.AddSingleton(userState);
services.AddSingleton(conversationState);
services.AddSingleton(userState.CreateProperty<UserProfile>("MyUserState"));
services.AddSingleton(conversationState.CreateProperty<DialogState>("MyBotDialogState"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc();
}
}
}
我的主要bot看起来像这样(不要管名称“ Echobot”):
public class EchoBot<T> : ActivityHandler where T : Dialog
{
private readonly BotState _userState;
private readonly BotState _conversationState;
private readonly Dialog _dialog;
private readonly ILogger _logger;
private readonly IStatePropertyAccessor<UserProfile> _userStateAccessor;
private readonly IStatePropertyAccessor<DialogState> _conversationDialogStateAccessor;
// Create cancellation token (used by Async Write operation).
public CancellationToken CancellationToken { get; private set; }
public EchoBot(ConversationState conversationState, UserState userState, T dialog, ILogger<EchoBot<T>> logger, IStatePropertyAccessor<UserProfile> userStatePropertyAccessor, IStatePropertyAccessor<DialogState> dialogStatePropertyAccessor)
{
_conversationState = conversationState;
_userState = userState;
_dialog = dialog;
_logger = logger;
_userStateAccessor = userStatePropertyAccessor;
_conversationDialogStateAccessor = dialogStatePropertyAccessor;
}
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default)
{
await base.OnTurnAsync(turnContext, cancellationToken);
var currentUserState = await _userStateAccessor.GetAsync(turnContext, () => new UserProfile(), cancellationToken);
var currentConversationDialogState = await _conversationDialogStateAccessor.GetAsync(turnContext, () => new DialogState(), cancellationToken);
await _userStateAccessor.SetAsync(turnContext, currentUserState, cancellationToken);
await _conversationDialogStateAccessor.SetAsync(turnContext, currentConversationDialogState, cancellationToken);
// Save any state changes that might have occured during the turn.
await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken=default)
{
_logger.LogInformation("Running dialog with Message Activity.");
//See DialogExtension.cs in the sample "complex-dialog" to see the Run method.
await _dialog.Run(turnContext, _conversationDialogStateAccessor, cancellationToken);
}
}
}
答案 0 :(得分:0)
现在,如果您从PartitionKey
中删除了CosmosDbStorageOptions
参数,它应该可以工作。由于您的容器当前已分区,您可能需要删除您的容器或使用其他名称。最简单的方法就是删除您的容器,然后让机器人为您创建一个容器。
提供了partitionKey时,所有Bot Builder SDK中目前都存在一个从分区数据库读取数据的错误。 Tracking the issue here