通过在bot框架v4中跳过第一个对话框的第一步,将第一个对话框的瀑布步骤调用到其他对话框中

时间:2019-11-28 03:55:31

标签: c# dialog frameworks bots robotframework

我的bot框架v4 C#项目中有3个对话框,每个对话框都有瀑布式步骤。

在第二个对话框中,其行为必须与第一个对话框相同,但不必执行第一个对话框的所有步骤,这意味着我需要跳过第一步。

通过跳过第一个对话框的第一步,有什么方法可以将第一个对话框的所有瀑布步骤调用到另一个对话框中。

1 个答案:

答案 0 :(得分:0)

waterfall一旦形成,就应该以逐步的方式执行。但是,您可以有条件地形成waterfall steps

此处的条件可以基于DialogId

很难理解您到底想做什么,我为您提供了一个示例解决方案。希望您也尝试这样做。

请参考以下代码:

MainDialog.cs

    namespace EchoBot.Dialogs
    {
        public class MainDialog : ComponentDialog
        {
            private readonly BotStateService _botStateService;

            public MainDialog(BotStateService botStateService) : base(nameof(MainDialog))
            {
                _botStateService = botStateService;

                InitializeWaterfallDialog();
            }

            private void InitializeWaterfallDialog()
            {
                var waterfallSteps = new WaterfallStep[]
                {
                    InitialStepAsync,
                    FinalStepAsync
                };

                AddDialog(new SecondDialog($"{nameof(MainDialog)}.second", _botStateService));
                AddDialog(new FirstDialog($"{nameof(MainDialog)}.first", _botStateService)); 
AddDialog(new FirstDialog($"{nameof(SecondDialog)}.firstFromSecond", _botStateService));
                AddDialog(new WaterfallDialog($"{nameof(MainDialog)}.mainFlow", waterfallSteps));

                InitialDialogId = $"{nameof(MainDialog)}.mainFlow";
            }

            private async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
            {
                if (Regex.Match(stepContext.Context.Activity.Text.ToLower(), "hi").Success)
                {
                    return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.second", null, cancellationToken);
                }
                else
                {
                    return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.first", null, cancellationToken);
                }

            }

            private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
            {
               return await stepContext.EndDialogAsync(null,cancellationToken);
            }
        } }

FirstDialog.cs

    namespace EchoBot.Dialogs
{
    public class FirstDialog : ComponentDialog
    {
        private readonly BotStateService _botStateService;

        public FirstDialog(string dialogId, BotStateService botStateService) : base(dialogId)
        {
            _botStateService = botStateService ?? throw new ArgumentNullException(nameof(botStateService));
            if (dialogId == $"{ nameof(MainDialog)}.first")
                InitializeWaterfallDialog1();
            else
                InitializeWaterfallDialog2();
        }

        private void InitializeWaterfallDialog1()
        {
            var waterfallsteps = new WaterfallStep[]
            {
                GetAge,
                GetCity,
                FinalStepAsync
            };
            AddDialog(new WaterfallDialog($"{nameof(FirstDialog)}.mainFlow", waterfallsteps));
            AddDialog(new NumberPrompt<int>($"{nameof(FirstDialog)}.age"));
            AddDialog(new TextPrompt($"{nameof(FirstDialog)}.city"));

            InitialDialogId = $"{nameof(FirstDialog)}.mainFlow";
        }
        private void InitializeWaterfallDialog2()
        {
            var waterfallsteps = new WaterfallStep[]
            {
                GetCity,
                FinalStepAsync
            };
            AddDialog(new WaterfallDialog($"{nameof(FirstDialog)}.mainFlow", waterfallsteps));
            AddDialog(new NumberPrompt<int>($"{nameof(FirstDialog)}.age"));
            AddDialog(new TextPrompt($"{nameof(FirstDialog)}.city"));

            InitialDialogId = $"{nameof(FirstDialog)}.mainFlow";
        }

        private async Task<DialogTurnResult> GetAge(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            return await stepContext.PromptAsync($"{nameof(FirstDialog)}.age",
                new PromptOptions
                {
                    Prompt = MessageFactory.Text("Please enter your age."),
                    RetryPrompt = MessageFactory.Text("Please enter a valid age.")
                }, cancellationToken);
        }

        private async Task<DialogTurnResult> GetCity(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            return await stepContext.PromptAsync($"{nameof(FirstDialog)}.age",
                 new PromptOptions
                 {
                     Prompt = MessageFactory.Text("Please enter your city."),
                     RetryPrompt = MessageFactory.Text("Please enter a valid city.")
                 }, cancellationToken);
        }

        private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            return await stepContext.EndDialogAsync(null, cancellationToken);
        }
    }}

SecondDialog.cs

    namespace EchoBot.Dialogs
{
    public class SecondDialog : ComponentDialog
    {
        private readonly BotStateService _botStateService;

        public SecondDialog(string dialogId, BotStateService botStateService) : base(dialogId) 
        {
            _botStateService = botStateService ?? throw new ArgumentNullException(nameof(botStateService));

            InitializeWaterfallDialog();
        }

        private void InitializeWaterfallDialog()
        {
            var waterfallSteps = new WaterfallStep[]
            {
                InitialStepAsync,
                FinalStepAsync
            };

            AddDialog(new WaterfallDialog($"{nameof(SecondDialog)}.mainFlow", waterfallSteps));
            AddDialog(new TextPrompt($"{nameof(SecondDialog)}.name"));


            InitialDialogId = $"{nameof(SecondDialog)}.mainFlow";
        }

        private async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
                return await stepContext.PromptAsync($"{nameof(SecondDialog)}.name",
                    new PromptOptions
                    {
                        Prompt = MessageFactory.Text("Please enter your Name.")
                    }, cancellationToken);
        }

        private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {

            //Suppose you want to call First Dialog from here
            return await stepContext.BeginDialogAsync($"{nameof(SecondDialog)}.firstFromSecond", null, cancellationToken);
        }
    }
}

添加了一行-AddDialog(new FirstDialog($"{nameof(SecondDialog)}.firstFromSecond", _botStateService));中的MainDialog.cs。对我来说很好。

图像1:当您从主对话框进入第二个对话框时,它询问名称,然后跳过“第一对话框”的第一步(即年龄),并询问第二步。城市。

From Second Dialog

图像2:当您直接从主对话框进入第一个对话框时,它将询问年龄和城市,即。它没有跳过第一步。

Directly First Dialog

希望这会有所帮助。在评论中询问是否有任何疑问!