我正在忙着编写一个与匿名用户和经过身份验证的用户交互的机器人 . 它将用户数据存储在自定义对象中,并将该对象持久保存到UserState Store .
当bot启动并且用户加入对话时,它会为自定义对象创建自定义对象和IStatePropertyAccessor . 然后,机器人确定这是否是经过身份验证的用户或匿名用户 . 如果经过身份验证,它会从后端系统加载所需的信息,并且我们可以在所有对话框中使用此数据而不会出现问题 .
如果它是匿名用户,我们会将他们引导到一个基本对话框,该对话框会获取他们的姓名,电话号码和电子邮件 . 此对话框的最后一步是提取上述自定义对象并使用收集的信息对其进行更新,以便在将请求保存到后端系统时将其附加 .
问题是更新的信息被保存到商店(我能够在cosmosDB中查看原始数据),但是当在其他对话框中从商店获取自定义对象时,它总是返回一个空对象 . 如果我再次触发入门对话框,它会将correclty填充的自定义对象拉出来 .
为什么这个对话框可以看到它保存到商店的数据,但其他对话框将其视为空对象?
下面是我在入门的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();
}
执行此步骤后,原始数据正确,正确设置了Fullname . 它可以在存储在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中的Fullname .
1 回答
事实证明,同事开发人员已将User Profile类的set属性设置为internal,因此访问者在读取商店时无法设置属性 .