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; }
        }
    }
希望这有帮助!如有疑问,请询问