C# BOT框架-使用Cosmos DB进行状态管理

C# BOT框架-使用Cosmos DB进行状态管理,c#,botframework,state-management,C#,Botframework,State Management,我已经在我的BOT框架中使用cosmosdb启用了日志记录和状态管理,如下链接所示 我也在我的Global.ascx中添加了以下代码 rotected void Application_Start() { Conversation.UpdateContainer( builder => { builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly

我已经在我的BOT框架中使用cosmosdb启用了日志记录和状态管理,如下链接所示

我也在我的Global.ascx中添加了以下代码

rotected void Application_Start()
{
    Conversation.UpdateContainer(
        builder =>
        {
            builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));
            // Bot Storage: register state storage for your bot
            var uri = new Uri(ConfigurationManager.AppSettings["DocumentDBUri"]);
            var key = ConfigurationManager.AppSettings["DocumentDBKey"];
            var store = new DocumentDbBotDataStore(uri, key);
            builder.Register(c => store)
                .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
                .AsSelf()
                .SingleInstance();
        });

    GlobalConfiguration.Configure(WebApiConfig.Register);
}
}


不相关,但实际上可以将代码的
var key
部分更改为
var key=Address.FromActivity(message)

使用下面的代码,我在屏幕截图中得到的结果有一些不同之处,其中之一是我没有使用您代码中的这一行
BotData BotData=new BotData()我还添加了这一行
wait botDataStore.FlushAsync(key,CancellationToken.None)我在
global.asax中拥有与您完全相同的代码

        if (activity.Type == ActivityTypes.Message)
        {

            var message = activity as IMessageActivity;
            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
            {
                var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
                var key = Address.FromActivity(message);

                ConversationReference r = new ConversationReference();
                var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);

                userData.SetProperty("userId", "123");

                userData.SetProperty("DOB", "some date");

                await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
                await botDataStore.FlushAsync(key, CancellationToken.None);
            }
            await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());

        }
if(activity.Type==ActivityTypes.Message)
{
var消息=活动作为IMessageActivity;
使用(var scope=DialogModule.BeginLifetimeScope(Conversation.Container,message))
{
var botDataStore=scope.Resolve();
var key=地址。FromActivity(消息);
ConversationReference r=新的ConversationReference();
var userData=await botDataStore.LoadAsync(key,BotStoreType.BotUserData,CancellationToken.None);
SetProperty(“userId”,“123”);
SetProperty(“DOB”,“某个日期”);
等待botDataStore.SaveAsync(key,BotStoreType.BotUserData,userData,CancellationToken.None);
等待botDataStore.FlushAsync(key,CancellationToken.None);
}
wait Conversation.sendaync(活动,()=>newdialogs.RootDialog());
}
我在我的宇宙数据库里得到了这个结果

希望这对你有帮助

编辑2018年4月12日

回答您的后续问题。要使其成为这段代码已经运行过的代码,您只需检查键上是否存在该值即可修改我提供给您的代码段,如下所示:

if (userData.GetProperty<string>("userId") == null)
{    
    userData.SetProperty("userId", "123");
    userData.SetProperty("DOB", "some date");
    await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
    await botDataStore.FlushAsync(key, CancellationToken.None);
}
if(userData.GetProperty(“userId”)==null)
{    
SetProperty(“userId”,“123”);
SetProperty(“DOB”,“某个日期”);
等待botDataStore.SaveAsync(key,BotStoreType.BotUserData,userData,CancellationToken.None);
等待botDataStore.FlushAsync(key,CancellationToken.None);
}
由于您没有访问上下文对象的权限,因此每次都需要运行其余的代码来检查状态


要回答关于用户关闭并重新打开窗口的其他问题,应该将其保存到您的cosmosDB中,这不应该是一个问题。

您所说的“(context.UserData.SetValue-works,但我希望它的状态客户端不会在cosmos DB中更新它)”是什么意思?它是用CosmosDBI编辑的带有示例代码的问题。我想在cosmos中保存自定义用户数据,并在任何需要的地方检索。但它并没有被保存为cosmos中数据属性的一部分。如果我使用context.UserData.SetValue,我可以检索它。但是它没有保存在cosmos中。
它没有保存为cosmos中数据属性的一部分
Hi@user3527063,代码对我有用,用户数据userId、DOB和username保存在cosmos中数据属性的一部分,我不确定我缺少了什么。你能分享你如何实现它的示例代码吗。保存和检索。谢谢!。这对我也很管用。我还有一个问题。每当用户键入某个内容时,它都会经历这个过程。我只想设置一次并在我的对话框中检索它。因此,我计划将此逻辑应用于Cortana和directline频道。如果用户关闭窗口并再次打开,所有内容是否都会重新开始。我将添加到我的答案中,以解决您的后续问题。如果这对你有效,请接受并投票回答:)
context.UserData.SetValue("username", "John Smith");
        if (activity.Type == ActivityTypes.Message)
        {

            var message = activity as IMessageActivity;
            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
            {
                var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
                var key = Address.FromActivity(message);

                ConversationReference r = new ConversationReference();
                var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);

                userData.SetProperty("userId", "123");

                userData.SetProperty("DOB", "some date");

                await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
                await botDataStore.FlushAsync(key, CancellationToken.None);
            }
            await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());

        }
if (userData.GetProperty<string>("userId") == null)
{    
    userData.SetProperty("userId", "123");
    userData.SetProperty("DOB", "some date");
    await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
    await botDataStore.FlushAsync(key, CancellationToken.None);
}