通过跳过 bot 框架 v4 中第一个对话的第一步,将第一个对话的瀑布步骤调用到其他对话中
Invoke the steps of waterfall of first dialog into other dialog by skipping the first step of a first dialog in bot framework v4
我的 bot 框架 v4 C# 项目中有 3 个对话框,每个对话框都有瀑布步骤。
在我的第二个对话框中,它的行为必须与第一个对话框相同,但它不必执行第一个对话框的所有步骤,这意味着我需要跳过第一步。
那么有什么方法可以通过跳过第一个对话的第一步将第一个对话的所有瀑布步骤调用到另一个对话中。
A waterfall
一旦形成就应该以 step-by-step 的方式执行。但是,您可以有条件地形成 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);
}
}
}
在 MainDialog.cs
中添加了一行 - AddDialog(new FirstDialog($"{nameof(SecondDialog)}.firstFromSecond", _botStateService));
。它对我来说很好用。
图片 1:当您从主对话框进入第二个对话框时,它会询问姓名,然后跳过第一个对话框的第一步(即年龄)并询问第二步即。城市。
图片 2:当您从主对话框直接进入第一个对话框时,它会询问年龄和城市,即。它没有跳过第一步。
希望这对您有所帮助。有任何疑问请在评论中提问!
我的 bot 框架 v4 C# 项目中有 3 个对话框,每个对话框都有瀑布步骤。
在我的第二个对话框中,它的行为必须与第一个对话框相同,但它不必执行第一个对话框的所有步骤,这意味着我需要跳过第一步。
那么有什么方法可以通过跳过第一个对话的第一步将第一个对话的所有瀑布步骤调用到另一个对话中。
A waterfall
一旦形成就应该以 step-by-step 的方式执行。但是,您可以有条件地形成 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);
}
}
}
在 MainDialog.cs
中添加了一行 - AddDialog(new FirstDialog($"{nameof(SecondDialog)}.firstFromSecond", _botStateService));
。它对我来说很好用。
图片 1:当您从主对话框进入第二个对话框时,它会询问姓名,然后跳过第一个对话框的第一步(即年龄)并询问第二步即。城市。
图片 2:当您从主对话框直接进入第一个对话框时,它会询问年龄和城市,即。它没有跳过第一步。
希望这对您有所帮助。有任何疑问请在评论中提问!