Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Cosmos,正在MessageController中检索对话数据_C#_Botframework_Azure Cosmosdb - Fatal编程技术网

C# Cosmos,正在MessageController中检索对话数据

C# Cosmos,正在MessageController中检索对话数据,c#,botframework,azure-cosmosdb,C#,Botframework,Azure Cosmosdb,我正在尝试用Azure提供的Cosmos存储替换InMemory存储 我正在对话数据中存储一些信息,在对话框中使用它,如果发送了某个命令,则从消息控制器中重置它 我在对话框中访问对话数据的方式是: context.ConversationData.GetValueOrDefault<String>("varName", ""); 如果我在内存中使用,前一行代码工作正常。我一切换到cosmos,代码的重置部分就失败了。调试该问题时,我发现返回的对话数据对象与从对话框中返回的数据对象不

我正在尝试用Azure提供的Cosmos存储替换InMemory存储

我正在对话数据中存储一些信息,在对话框中使用它,如果发送了某个命令,则从消息控制器中重置它

我在对话框中访问对话数据的方式是:

context.ConversationData.GetValueOrDefault<String>("varName", "");
如果我在内存中使用,前一行代码工作正常。我一切换到cosmos,代码的重置部分就失败了。调试该问题时,我发现返回的对话数据对象与从对话框中返回的数据对象不同,因此无法重置变量

这是我连接cosmos数据库的方式:

var uri = new Uri(ConfigurationManager.AppSettings["DocumentDbUrl"]);
var key = ConfigurationManager.AppSettings["DocumentDbKey"];
var store = new DocumentDbBotDataStore(uri, key);

Conversation.UpdateContainer(
builder = >{
    builder.Register(c = >store).Keyed < IBotDataStore < BotData >> (AzureModule.Key_DataStore).AsSelf().SingleInstance();

    builder.Register(c = >new CachingBotDataStore(store, CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency)).As < IBotDataStore < BotData >> ().AsSelf().InstancePerLifetimeScope();

});
var uri=new uri(ConfigurationManager.AppSettings[“DocumentDbUrl]”);
var key=ConfigurationManager.AppSettings[“DocumentDbKey”];
var store=newdocumentdbbotdatastore(uri,键);
Conversation.UpdateContainer(
生成器=>{
builder.Register(c=>store).Keyed>(AzureModule.Key\u DataStore.AsSelf().SingleInstance();
注册(c=>新的CachingBotDataStore(store,cachingbotdatastoreconsistentypolicy.ETagBasedConsistency)).As>().AsSelf().InstancePerLifetimeScope();
});
知道为什么会这样吗

编辑:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    {
        if (activity.Text=="reset")
        {
            var message = activity as IMessageActivity;

            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
            {
                var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
                var key = new AddressKey()
                {
                    BotId = message.Recipient.Id,
                    ChannelId = message.ChannelId,
                    UserId = message.From.Id,
                    ConversationId = message.Conversation.Id,
                    ServiceUrl = message.ServiceUrl
                };
                var userData = await botDataStore.LoadAsync(key, BotStoreType.BotConversationData, CancellationToken.None);

                //var varName = userData.GetProperty<string>("varName");

                userData.SetProperty<object>("varName", null);

                await botDataStore.SaveAsync(key, BotStoreType.BotConversationData, userData, CancellationToken.None);
                await botDataStore.FlushAsync(key, CancellationToken.None);
            }
        }

        await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
    }
    else
    {
        HandleSystemMessage(activity);
    }
    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

public class AddressKey : IAddress
{
    public string BotId { get; set; }
    public string ChannelId { get; set; }
    public string ConversationId { get; set; }
    public string ServiceUrl { get; set; }
    public string UserId { get; set; }
}
当使用im内存存储时,该代码工作正常,但用cosmos存储替换该存储时无法检索对话框外的对话数据(对话框正确获取/设置对话数据,但StateConts无法正确检索数据。它返回一个空对象,但奇怪的是,它与从对话框返回的对话ID相同)

调试该问题时,我发现返回的对话数据对象与从对话框中返回的数据对象不同,因此无法重置变量

请确保在保存数据和重置数据操作时使用的是相同的对话

此外,我使用以下示例代码进行了测试,我可以按预期保存和重置对话数据

在消息控制器中:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    {
        if (activity.Text=="reset")
        {
            var message = activity as IMessageActivity;

            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
            {
                var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
                var key = new AddressKey()
                {
                    BotId = message.Recipient.Id,
                    ChannelId = message.ChannelId,
                    UserId = message.From.Id,
                    ConversationId = message.Conversation.Id,
                    ServiceUrl = message.ServiceUrl
                };
                var userData = await botDataStore.LoadAsync(key, BotStoreType.BotConversationData, CancellationToken.None);

                //var varName = userData.GetProperty<string>("varName");

                userData.SetProperty<object>("varName", null);

                await botDataStore.SaveAsync(key, BotStoreType.BotConversationData, userData, CancellationToken.None);
                await botDataStore.FlushAsync(key, CancellationToken.None);
            }
        }

        await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
    }
    else
    {
        HandleSystemMessage(activity);
    }
    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

public class AddressKey : IAddress
{
    public string BotId { get; set; }
    public string ChannelId { get; set; }
    public string ConversationId { get; set; }
    public string ServiceUrl { get; set; }
    public string UserId { get; set; }
}
公共异步任务发布([FromBody]活动)
{
if(activity.Type==ActivityTypes.Message)
{
如果(activity.Text==“重置”)
{
var消息=活动作为IMessageActivity;
使用(var scope=DialogModule.BeginLifetimeScope(Conversation.Container,message))
{
var botDataStore=scope.Resolve();
var key=new AddressKey()
{
BotId=message.Recipient.Id,
ChannelId=message.ChannelId,
UserId=message.From.Id,
ConversationId=message.Conversation.Id,
ServiceUrl=message.ServiceUrl
};
var userData=await botDataStore.LoadAsync(key,BotStoreType.BotConversationData,CancellationToken.None);
//var varName=userData.GetProperty(“varName”);
SetProperty(“varName”,null);
等待botDataStore.SaveAsync(key,BotStoreType.BotConversationData,userData,CancellationToken.None);
等待botDataStore.FlushAsync(key,CancellationToken.None);
}
}
wait Conversation.sendaync(活动,()=>newdialogs.RootDialog());
}
其他的
{
HandleSystemMessage(活动);
}
var response=Request.CreateResponse(HttpStatusCode.OK);
返回响应;
}
公共类地址键:IAddress
{
公共字符串BotId{get;set;}
公共字符串ChannelId{get;set;}
公共字符串会话ID{get;set;}
公共字符串ServiceUrl{get;set;}
公共字符串用户标识{get;set;}
}
在对话框中:

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
    var activity = await result as Activity;

    // calculate something for us to return
    int length = (activity.Text ?? string.Empty).Length;

    var varName = "";

    if (activity.Text.ToLower().Contains("hello"))
    {
        context.ConversationData.SetValue<string>("varName", activity.Text);
    }

    if (activity.Text.ToLower().Contains("getval"))
    {
        varName = context.ConversationData.GetValueOrDefault<string>("varName", "");

        activity.Text = $"{varName} form cosmos";
    }

    if (activity.Text.ToLower().Contains("remove"))
    {
        activity.Text = "varName is removed";
    }

    // return our reply to the user
    await context.PostAsync($"{activity.Text}");

    context.Wait(MessageReceivedAsync);
}
专用异步任务消息ReceivedAsync(IDialogContext上下文,IAwaitable结果)
{
var活动=等待作为活动的结果;
//算点东西让我们回去
int length=(activity.Text??string.Empty).length;
var varName=“”;
if(activity.Text.ToLower().Contains(“hello”))
{
context.ConversationData.SetValue(“varName”,activity.Text);
}
if(activity.Text.ToLower().Contains(“getval”))
{
varName=context.ConversationData.GetValueOrDefault(“varName”,即“”);
activity.Text=$“{varName}form cosmos”;
}
if(activity.Text.ToLower()包含(“删除”))
{
activity.Text=“varName已删除”;
}
//将我们的回复返回给用户
wait context.PostAsync($“{activity.Text}”);
Wait(MessageReceivedAsync);
}
测试步骤:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    {
        if (activity.Text=="reset")
        {
            var message = activity as IMessageActivity;

            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
            {
                var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
                var key = new AddressKey()
                {
                    BotId = message.Recipient.Id,
                    ChannelId = message.ChannelId,
                    UserId = message.From.Id,
                    ConversationId = message.Conversation.Id,
                    ServiceUrl = message.ServiceUrl
                };
                var userData = await botDataStore.LoadAsync(key, BotStoreType.BotConversationData, CancellationToken.None);

                //var varName = userData.GetProperty<string>("varName");

                userData.SetProperty<object>("varName", null);

                await botDataStore.SaveAsync(key, BotStoreType.BotConversationData, userData, CancellationToken.None);
                await botDataStore.FlushAsync(key, CancellationToken.None);
            }
        }

        await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
    }
    else
    {
        HandleSystemMessage(activity);
    }
    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

public class AddressKey : IAddress
{
    public string BotId { get; set; }
    public string ChannelId { get; set; }
    public string ConversationId { get; set; }
    public string ServiceUrl { get; set; }
    public string UserId { get; set; }
}

输入
hello bot
后,可以在Cosmosdb中找到它作为对话数据保存。

输入“重置”后,可以找到
varName
的值重置为
null


活动。GetStateClient()不推荐使用:


它仅使用默认的状态服务。如果您正在使用BotBuilder Azure作为状态,则将不会使用.GetStateClient()检索您的CosmosDb实现。请参考@Fei的答案,了解如何使用DialogModule.BeginLifetimeScopedialog.Context方法操作状态。

您使用cosmo存储吗?因为我提到了代码示例对于inMemory存储很有效,是的,我确定我使用的是相同的对话,并且我确保了Convert在这两种情况下检索到的id都是相同的。
您使用过cosmo存储吗?
是的,我使用的是Cosmosdb。您可以找到截图是我在Cosmosdb数据资源管理器中看到的数据。我不知道为什么它以前不适用于我,但现在可以了!谢谢。@FeiHan试图理解您的代码