如何在V4 Bot Framework中的对话框外读取状态属性访问器

时间:2019-05-30 16:50:23

标签: botframework

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

GitHub

在上述GitHub示例中,我们有一个验证器AgePromptValidatorAsync,用于验证年龄。 但是我想访问存储在State属性中的Name。 如何做到这一点。 并且可以在不包含上下文的对话框外部方法中访问状态/使用GetAsync

@mdrichardson,您能帮我吗。谢谢您。

1 个答案:

答案 0 :(得分:0)

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传递给使用它的任何方法/函数。几乎每个您要使用的bot方法都具有某种上下文,您可以将其传递给另一个方法。这绝对是您最好的选择。
  2. 创建一个单独的类,用于在机器人内存中存储变量
  3. 您用来跟踪UserProfile的Write Directly to StorageImplement Custom Storage。请注意,您必须传递存储对象,因此也可以传递上下文。
  4. Adaptive Dialogs起使用新的they do state management differently。但是,我强烈建议您不要这样做,因为它们是“实验性的”,这意味着仍然存在错误,我们几乎没有在内部使用它。我将其添加为后代和希望使用新玩意的用户的更多选择。