自定义状态未加载保存到数据存储的数据

时间:2018-11-26 13:25:52

标签: c# botframework

我正忙着编写一个与匿名用户和经过身份验证的用户进行交互的机器人。它将用户数据存储在自定义对象中,并将该对象持久保存到UserState存储中。

当漫游器启动并且用户加入对话时,它将创建自定义对象和该自定义对象的IStatePropertyAccessor。然后,漫游器会确定这是经过身份验证的用户还是匿名用户。如果其经过验证,它将从后端系统加载所需的信息,我们可以在所有对话框中使用此数据而不会出现问题。

如果它是匿名用户,我们会将其定向到一个基本对话框,该对话框将获取其名称,电话号码和电子邮件。该对话框的最后一步是提取上面的自定义对象,并使用收集的信息对其进行更新,以便在将请求保存到后端系统时可以附加它。

问题是更新的信息保存到存储中(我可以在cosmosDB中查看原始数据),但是在其他对话框中从存储中获取自定义对象时,它总是返回一个空对象。如果我再次触发入职对话框,它将正确地填充正确的自定义对象。

为什么这个对话框可以看到保存到商店的数据,而其他对话框却将其视为空对象?

下面是我在入职的WaterfallStep对话框中最后一步的代码:

public async Task<DialogTurnResult> ProcessOnBoardingAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        _form = await _accessor.GetAsync(stepContext.Context);
        _form.Firstname = (string)stepContext.Result;

        UserProfile profile = await _userAccessor.GetAsync(stepContext.Context);

        profile.FullName = String.Format("{0} {1}", _form.Firstname, _form.Lastname);

        await _userAccessor.SetAsync(stepContext.Context, profile);

        MainResponses view = new MainResponses();
        await view.ReplyWith(stepContext.Context, MainResponses.Menu);

        return await stepContext.EndDialogAsync();
    }

此步骤之后,原始数据正确,全名设置正确。可以在CosmosDB中存储的原始数据中查看它。

下一个对话框的构造函数如下,传递给该构造函数的IStatePropertyAccessor<UserProfile> userAccessor与传递给Onboarding Dialog构造函数的那个​​相同:

public LeadDialog(BotServices botServices, IStatePropertyAccessor<LeadForm> accessor, IStatePropertyAccessor<UserProfile> userAccessor)
        : base(botServices, nameof(LeadDialog))
    {
        _accessor = accessor;
        _userAccessor = userAccessor;

        InitialDialogId = nameof(LeadDialog);

        var lead = new WaterfallStep[]
        {
            LeadPromptForTitleAsync,
            LeadPromptForDescriptionAcync,
            LeadProcessFormAsync
        };

        AddDialog(new WaterfallDialog(InitialDialogId, lead));
        AddDialog(new TextPrompt("LeadTopic"));
        AddDialog(new TextPrompt("LeadDescription"));
    }

,正在尝试使用访问器的代码是:

public async Task<DialogTurnResult> LeadProcessFormAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        _form = await _accessor.GetAsync(stepContext.Context);
        _form.Description = (string)stepContext.Result;

        await _responder.ReplyWith(stepContext.Context, LeadResponses.LeadFinish);
        await _responder.ReplyWith(stepContext.Context, LeadResponses.LeadSummary, new { _form.Topic, _form.Description });

        UserProfile profile = await _userAccessor.GetAsync(stepContext.Context);


        var LeadDetail = new CRMLead
        {
            ks_chatid = profile.Chatid,
            parentcontactid =profile.ContactId,
            topic = _form.Topic,
            description = _form.Description
        };
    }

在这最后的代码中,返回的UserProfile是一个空对象,具有默认值,但至少应该提取出正确存储在CosmosDB中的全名。

1 个答案:

答案 0 :(得分:0)

事实证明,有位开发人员将User Profile类的设置属性设置为内部属性,因此访问者在读取商店时无法设置属性。