【问题标题】:How to read state property accessors outside the dialog in V4 Bot Framework如何在 V4 Bot Framework 中的对话框之外读取状态属性访问器
【发布时间】:2019-10-16 08:31:13
【问题描述】:

我正在使用 bot 框架版本 4。我想在验证器方法中访问用户状态属性,但我没有找到任何解决方案。

GitHub

在上面的 GitHub 示例中,我们有一个验证器 AgePromptValidatorAsync 来验证年龄。 但我想访问我存储在 State 属性中的 Name 。 怎么可能达到。 是否可以在不包含上下文的对话框之外的方法中访问状态/使用GetAsync

@mdrichardson 你能帮我吗?提前谢谢你。

【问题讨论】:

  • 已答复。并注意:不要担心叫我们的名字。 @.mentions 实际上不会发送通知,除非我们已经评论/回答了这个问题。不过,我们每天早上都会检查所有botframework 标签,然后将它们分配出去——通常是给那些认为他们可以回答的人。
  • 非常感谢。你的回答真的帮助了我。抱歉迟到了,我忙于其他工作。
  • 没问题。很高兴我能帮上忙!

标签: botframework


【解决方案1】:

1。确保在点击验证之前保存UserProfile.Name

该示例不会自行执行此操作,因此您可以:

private async Task<DialogTurnResult> NameConfirmStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    stepContext.Values["name"] = (string)stepContext.Result;

    // ADDED: This code block saves the Name
    if (!string.IsNullOrEmpty((string)stepContext.Result)) {
        var userProfile = await _userProfileAccessor.GetAsync(stepContext.Context, () => new UserProfile(), cancellationToken);
        userProfile.Name = (string)stepContext.Result;
        await _userProfileAccessor.SetAsync(stepContext.Context, userProfile);
    }

    // We can send messages to the user at any point in the WaterfallStep.
    await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Thanks {stepContext.Result}."), cancellationToken);

    // WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
    return await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text("Would you like to give your age?") }, cancellationToken);
}

2。访问用户配置文件

// CHANGED: Since this accesses the userProfile, the method is no longer static. Also must be async
private async Task<bool> AgePromptValidatorAsync(PromptValidatorContext<int> promptContext, CancellationToken cancellationToken)
{
    // ADDED: Here is how you can access the Name
    //   Note: You can use promptContext.Context instead of stepContext.Context since they're both ITurnContext
    var userProfile = await _userProfileAccessor.GetAsync(promptContext.Context, () => new UserProfile(), cancellationToken);
    var name = userProfile.Name;
    // Do whatever you want with the Name

    // CHANGED: Since this is now async, we don't return Task.FromResult(). We just return the result
    return promptContext.Recognized.Succeeded && promptContext.Recognized.Value > 0 && promptContext.Recognized.Value < 150;
}

在没有上下文的情况下访问 UserProfile

这是可能的,但您不能轻松地或开箱即用地做到这一点。但是,您可以使用一些选项(主要是按照从最难到最难的顺序):

  1. context 传递给您需要在其中使用它的任何方法/函数。几乎您使用的每个机器人方法都有某种可以传递给另一个方法的上下文。这绝对是您的最佳选择。
  2. 创建一个单独的类,用于在机器人内存中存储变量
  3. Write Directly to StorageImplement Custom Storage 用于跟踪用户配置文件。请注意,您必须传递您的 Storage 对象,因此您也可以只传递上下文。
  4. 使用新的Adaptive Dialogs,因为they do state management differently。不过,我强烈建议不要这样做,因为这些是“实验性的”,这意味着仍然存在错误,我们几乎没有在内部使用它。我将此添加为一个选项,以供后代和想要玩新东西的用户使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多