Azure 如何在对话框启动时将外部状态传递给它?
例如,我有一个包含城市名称的州,并将其存储在对话状态中 当我启动对话框时,对话框会询问用户城市名称,并结束对话框 接下来,对话框再次启动,但我希望这次对话框已经从外部范围获得了城市名称,而不是再次询问用户 我知道瀑布对话可以做到这一点,每一步都可以从最后一步得到结果。但我想知道如何在对话之间实现它 请给我看更多的细节和样品。Azure 如何在对话框启动时将外部状态传递给它?,azure,botframework,Azure,Botframework,例如,我有一个包含城市名称的州,并将其存储在对话状态中 当我启动对话框时,对话框会询问用户城市名称,并结束对话框 接下来,对话框再次启动,但我希望这次对话框已经从外部范围获得了城市名称,而不是再次询问用户 我知道瀑布对话可以做到这一点,每一步都可以从最后一步得到结果。但我想知道如何在对话之间实现它 请给我看更多的细节和样品。 谢谢我的问题类似于。每次用户输入消息时,您都需要保存您的状态 首先在BotStateService.cs中生成状态变量 在DialogBot.cs中,每次用户输入消息时,它
谢谢我的问题类似于。每次用户输入消息时,您都需要保存您的状态 首先在BotStateService.cs中生成状态变量 在DialogBot.cs中,每次用户输入消息时,它都会进入OnTurnAsync方法,将您的状态保存在那里 你可以试试这个办法 BotStateService.cs:
namespace CoreBot.Services
{
public class BotStateService
{
//state variables
public UserState _userState { get; }
public ConversationState _conversationState { get; }
public DialogState _dialogState { get; }
//IDs
public static string UserProfileId { get; } = $"{nameof(BotStateService)}.UserProfile";
public static string ConversationDataId { get; } = $"{nameof(ConversationState)}.ConversationData";
public static string DialogStateId { get; } = $"{nameof(DialogState)}.DialogState";
//Accessors
public IStatePropertyAccessor<UserProfile> UserProfileAccessors { get; set; }
public IStatePropertyAccessor<ConversationData> ConversationDataAccessors { get; set; }
public IStatePropertyAccessor<DialogState> DialogStateAccessors { get; set; }
public BotStateService(UserState userState, ConversationState conversationState)
{
_userState = userState ?? throw new ArgumentNullException(nameof(userState));
_conversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
InitializeAccessors();
}
private void InitializeAccessors()
{
UserProfileAccessors = _userState.CreateProperty<UserProfile>(UserProfileId);
ConversationDataAccessors = _conversationState.CreateProperty<ConversationData>(ConversationDataId);
DialogStateAccessors = _conversationState.CreateProperty<DialogState>(DialogStateId);
}
}
}
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default)
{
// Save your state each time user enters the conversation or enters a message
await base.OnTurnAsync(turnContext, cancellationToken);
await _botStateService._userState.SaveChangesAsync(turnContext);
await _botStateService._conversationState.SaveChangesAsync(turnContext);
}
private async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
UserProfile userProfile = await _botStateService.UserProfileAccessors.GetAsync(stepContext.Context, () => new UserProfile());
if (String.IsNullOrEmpty(userProfile.city))
{
return await stepContext.PromptAsync($"{nameof(GreetingDialog)}.city",
new PromptOptions
{
Prompt = MessageFactory.Text("Please tell me name of your city.")
}, cancellationToken);
}
else
{
return await stepContext.NextAsync(null, cancellationToken);
}
}
private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
UserProfile userProfile = await _botStateService.UserProfileAccessors.GetAsync(stepContext.Context, () => new UserProfile());
if (String.IsNullOrEmpty(userProfile.city))
{
userProfile.city = (String)stepContext.Result;
await _botStateService.UserProfileAccessors.SetAsync(stepContext.Context, userProfile);
}
return await stepContext.EndDialogAsync(null, cancellationToken);
}
using System;
namespace CoreBot.Profiles
{
public class UserProfile
{
public string city { get; set; }
}
}
GreetingDialog.cs:
namespace CoreBot.Services
{
public class BotStateService
{
//state variables
public UserState _userState { get; }
public ConversationState _conversationState { get; }
public DialogState _dialogState { get; }
//IDs
public static string UserProfileId { get; } = $"{nameof(BotStateService)}.UserProfile";
public static string ConversationDataId { get; } = $"{nameof(ConversationState)}.ConversationData";
public static string DialogStateId { get; } = $"{nameof(DialogState)}.DialogState";
//Accessors
public IStatePropertyAccessor<UserProfile> UserProfileAccessors { get; set; }
public IStatePropertyAccessor<ConversationData> ConversationDataAccessors { get; set; }
public IStatePropertyAccessor<DialogState> DialogStateAccessors { get; set; }
public BotStateService(UserState userState, ConversationState conversationState)
{
_userState = userState ?? throw new ArgumentNullException(nameof(userState));
_conversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
InitializeAccessors();
}
private void InitializeAccessors()
{
UserProfileAccessors = _userState.CreateProperty<UserProfile>(UserProfileId);
ConversationDataAccessors = _conversationState.CreateProperty<ConversationData>(ConversationDataId);
DialogStateAccessors = _conversationState.CreateProperty<DialogState>(DialogStateId);
}
}
}
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default)
{
// Save your state each time user enters the conversation or enters a message
await base.OnTurnAsync(turnContext, cancellationToken);
await _botStateService._userState.SaveChangesAsync(turnContext);
await _botStateService._conversationState.SaveChangesAsync(turnContext);
}
private async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
UserProfile userProfile = await _botStateService.UserProfileAccessors.GetAsync(stepContext.Context, () => new UserProfile());
if (String.IsNullOrEmpty(userProfile.city))
{
return await stepContext.PromptAsync($"{nameof(GreetingDialog)}.city",
new PromptOptions
{
Prompt = MessageFactory.Text("Please tell me name of your city.")
}, cancellationToken);
}
else
{
return await stepContext.NextAsync(null, cancellationToken);
}
}
private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
UserProfile userProfile = await _botStateService.UserProfileAccessors.GetAsync(stepContext.Context, () => new UserProfile());
if (String.IsNullOrEmpty(userProfile.city))
{
userProfile.city = (String)stepContext.Result;
await _botStateService.UserProfileAccessors.SetAsync(stepContext.Context, userProfile);
}
return await stepContext.EndDialogAsync(null, cancellationToken);
}
using System;
namespace CoreBot.Profiles
{
public class UserProfile
{
public string city { get; set; }
}
}
希望这有帮助!如有疑问,请询问