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;
}
Доступ к профилю пользователя без контекста
Это возможно, но вы не можете сделать это легко или из коробки. Однако есть несколько опций, которые вы можете использовать (в основном в порядке от наименее сложного до большинства):
- Передайте
context
любому методу / функции, в котором вы хотите его использовать. Почти каждый метод бота, который вы используете, имеет некоторый контекст, который вы можете передать в другой метод. Это определенно ваш лучший вариант.
- Создайте отдельный класс, который вы используете для хранения переменных в памяти бота
- Либо Запись непосредственно в хранилище или Реализация пользовательского хранилища , которое вы используете для отслеживания UserProfile. Обратите внимание, что вам придется обойти свой объект Storage, так что вместо этого вы можете просто обойти контекст.
- Используйте новые Адаптивные диалоги , поскольку они управляют состоянием по-разному . Однако я настоятельно рекомендую против этого, поскольку они являются «экспериментальными», что означает, что все еще есть ошибки, и мы едва используем это внутри. Я добавляю это как вариант больше для потомков и пользователей, которые хотят играть с новыми вещами.