Как прочитать средства доступа к свойствам состояния вне диалога в V4 Bot Framework - PullRequest
1 голос
/ 30 мая 2019

Я использую Bot Framework версии 4. Я хотел бы получить доступ к свойствам состояния пользователя в методе валидатора, но я не нашел никакого решения.

GitHub

В приведенном выше примере с GitHub у нас есть валидатор AgePromptValidatorAsync, который проверяет возраст.Но я хотел бы получить доступ к имени, которое я сохранил в государственной собственности.Как это могло быть достигнуто.И возможно ли получить доступ к состоянию / использованию GetAsync в методе вне диалога, который не содержит контекста.

@ mdrichardson Не могли бы вы помочь мне в этом. Заранее спасибо.

1 Ответ

0 голосов
/ 31 мая 2019

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;
}

Доступ к профилю пользователя без контекста

Это возможно, но вы не можете сделать это легко или из коробки. Однако есть несколько опций, которые вы можете использовать (в основном в порядке от наименее сложного до большинства):

  1. Передайте context любому методу / функции, в котором вы хотите его использовать. Почти каждый метод бота, который вы используете, имеет некоторый контекст, который вы можете передать в другой метод. Это определенно ваш лучший вариант.
  2. Создайте отдельный класс, который вы используете для хранения переменных в памяти бота
  3. Либо Запись непосредственно в хранилище или Реализация пользовательского хранилища , которое вы используете для отслеживания UserProfile. Обратите внимание, что вам придется обойти свой объект Storage, так что вместо этого вы можете просто обойти контекст.
  4. Используйте новые Адаптивные диалоги , поскольку они управляют состоянием по-разному . Однако я настоятельно рекомендую против этого, поскольку они являются «экспериментальными», что означает, что все еще есть ошибки, и мы едва используем это внутри. Я добавляю это как вариант больше для потомков и пользователей, которые хотят играть с новыми вещами.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...