我正在使用 Microsoft Bot Framework V4 版本制作一个机器人。该文档真的很糟糕,当我尝试存储 de UserSate 和 ConversationState 时,我在使用 Cosmos DB (Azure) 时遇到了问题。
我尝试了 Google 中的所有结果,但还没有任何效果。另外,实际上并没有太多关于该框架的信息。
下面是Startup.cs文件的代码。
public void ConfigureServices(IServiceCollection services)
{
services.AddBot<SeguritoBot>(options =>
{
var secretKey = Configuration.GetSection("botFileSecret")?.Value;
var botFilePath = Configuration.GetSection("botFilePath")?.Value;
// Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
var botConfig = BotConfiguration.Load(botFilePath ?? @".\Segurito.bot", secretKey);
services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})"));
// Retrieve current endpoint.
var environment = _isProduction ? "production" : "development";
var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment);
if (!(service is EndpointService endpointService))
{
throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
}
options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);
// Creates a logger for the application to use.
ILogger logger = _loggerFactory.CreateLogger<SeguritoBot>();
// Catches any errors that occur during a conversation turn and logs them.
options.OnTurnError = async (context, exception) =>
{
logger.LogError($"Exception caught : {exception}");
await context.SendActivityAsync("Sorry, it looks like something went wrong.");
};
var optionsConversation = new CosmosDbStorageOptions()
{
CosmosDBEndpoint = new Uri("--secret--"),
AuthKey = "--secret--",
DatabaseId = "--secret--",
CollectionId = "--secret--"
};
var optionsUser = new CosmosDbStorageOptions()
{
CosmosDBEndpoint = new Uri("--secret--"),
AuthKey = "--secret--",
DatabaseId = "--secret--",
CollectionId = "--secret--"
};
IStorage dataStoreConversationState = new CosmosDbStorage(optionsConversation);
IStorage dataStoreUserState = new CosmosDbStorage(optionsUser);
options.Middleware.Add(new ConversationState<ConversationState>(dataStoreConversationState));
options.Middleware.Add(new UserState<UserState>(dataStoreUserState));
});
}
最后一行给出错误:
The non-generic type 'ConversationState' cannot be used with type arguments
The non-generic type 'ConversationState' cannot be used with type arguments
最佳答案
好吧,我不确定您从哪里获得此代码,但它看起来像是来自预发布版本。 ConversationState
和UserState
不再是中间件,也不再通用(例如没有类型参数)。
这就是Startup::ConfigureServices
在 4.x 版本构建上使用 CosmosDB 进行状态存储时应该类似于:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Only need a single storage instance unless you really are storing your conversation state and user state in two completely DB instances
var storage = new CosmosDbStorage(new CosmosDbStorageOptions
{
// … set options here …
});
var conversationState = new ConversationState(storage);
var userState = new UserState(storage);
// Add the states as singletons
services.AddSingleton(conversationState);
services.AddSingleton(userState);
// Create state properties accessors and register them as singletons
services.AddSingleton(conversationState.CreateProperty<YourBotConversationState>("MyBotConversationState"));
services.AddSingleton(userState.CreateProperty<YourBotUserState>("MyBotUserState"));
services.AddBot<SeguritoBot>(options =>
{
// … set options here …
});
}
}
现在,在您的机器人中,如果您想访问这些属性,您可以通过构造函数将它们作为依赖项:
public class SeguritoBot : IBot
{
private readonly ConversationState _conversationState;
private readonly UserState _userState;
private readonly IStatePropertyAccessor<YourBotConversationState> _conversationStatePropertyAccessor;
private readonly IStatePropertyAccessor<YourBotUserState> _userStatePropertyAccessor;
public SeguritoBot(
ConversationState conversationState,
UserState userState,
IStatePropertyAccessor<YourBotConversationState> conversationStatePropertyAccessor,
IStatePropertyAccessor<YourBotUserState> userStatePropertyAccesssor)
{
_conversationState = conversationState;
_userState = userState;
_conversationStatePropertyAcessor = conversationStatePropertyAcessor;
_userStatePropertyAcessor = userStatePropertyAcessor;
}
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
var currentConversationState = await _conversationStatePropertyAccessor.GetAsync(
turnContext,
() => new YourBotConversationState(),
cancellationToken);
// Access properties for this conversation
// currentConversationState.SomeProperty
// Update your conversation state property
await _conversationStatePropertyAccessor.SetAsync(turnContext, currentConversationState, cancellationToken);
// Commit any/all changes to conversation state properties
await _conversationState.SaveChangesAsync(turnContext, cancellationToken);
}
}
显然,您可以对用户状态属性执行相同的操作,并且可以通过更多调用 CreateProperty
支持每个状态范围的多个属性。并注入(inject)那些IStatePropertyAccessor<T>
还有等等
关于c# - 如何在 Azure Cosmos DB (BotFramework) 中存储 UserState 和 ConversationState?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54117431/