在我的OnTurnAsync
中,我在单独的类中调用主对话框。并且主对话框也从其他类调用其他对话框,依此类推。这是分离和扩展Dialog的正确方法吗?我每个人都创建了单独的“组件对话框”。因为我的对话很漫长,并且在主Bot类中进行所有对话都很麻烦。
主对话框:
public class MainDialog : ComponentDialog
{
private const string InitialId = "mainDialog";
private const string ChoicePrompt = "choicePrompt";
private const string DialogAId = "dialogAId";
public MainDialog(string dialogId)
: base(dialogId)
{
InitialDialogId = InitialId;
WaterfallStep[] waterfallSteps = new WaterfallStep[]
{
FirstStepAsync,
SecondStepAsync,
ContinueStepAsync,
ThirdStepAsync,
};
AddDialog(new WaterfallDialog(InitialId, waterfallSteps));
AddDialog(new ChoicePrompt(ChoicePrompt));
AddDialog(new DialogA(DialogAId));
}
private static async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
return await stepContext.PromptAsync(
ChoicePrompt,
new PromptOptions
{
Prompt = MessageFactory.Text($"Here are your choices:"),
Choices = new List<Choice>
{
new Choice
{
Value = "Open Dialog A",
},
new Choice
{
Value = "Open Dialog B",
},
},
RetryPrompt = MessageFactory.Text($"Please choose one of the options."),
});
}
private static async Task<DialogTurnResult> SecondStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
var response = (stepContext.Result as FoundChoice)?.Value.ToLower();
if (response == "open dialog a")
{
return await stepContext.BeginDialogAsync(DialogAId, cancellationToken: cancellationToken);
}
if (response == "open dialog b")
{
// re-prompt not working btw
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Dialog B is not ready need to reprompt previous step."));
await stepContext.RepromptDialogAsync();
}
return await stepContext.NextAsync();
}
private static async Task<DialogTurnResult> ThirdStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
// what is the best way to end this?
// return await stepContext.ReplaceDialogAsync(InitialId);
return await stepContext.EndDialogAsync();
}
}
对话框A代码:
public class DialogA : ComponentDialog
{
private const string InitialId = "dialogA";
private const string ChoicePrompt = "choicePrompt";
private const string DialogAchildId = "dialogA_childId";
public DialogA(string dialogId)
: base(dialogId)
{
InitialDialogId = InitialId;
WaterfallStep[] waterfallSteps = new WaterfallStep[]
{
FirstStepAsync,
SecondStepAsync,
ContinueStepAsync,
ThirdStepAsync,
};
AddDialog(new WaterfallDialog(InitialId, waterfallSteps));
AddDialog(new ChoicePrompt(ChoicePrompt));
AddDialog(new DialogA_child(DialogAchildId));
}
private static async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
return await stepContext.PromptAsync(
ChoicePrompt,
new PromptOptions
{
Prompt = MessageFactory.Text($"Here are your choices:"),
Choices = new List<Choice>
{
new Choice
{
Value = "Open Dialog A_Child",
},
new Choice
{
Value = "Open Dialog B_Child",
},
},
RetryPrompt = MessageFactory.Text($"Please choose one of the options."),
});
}
private static async Task<DialogTurnResult> SecondStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
var response = (stepContext.Result as FoundChoice)?.Value.ToLower();
if (response == "open dialog a_child")
{
return await stepContext.BeginDialogAsync(DialogAchildId, cancellationToken: cancellationToken);
}
if (response == "open dialog b_child")
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Dialog B_child is not ready need to reprompt previous step."));
await stepContext.RepromptDialogAsync();
}
return await stepContext.NextAsync();
}
private static async Task<DialogTurnResult> ContinueStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"should continue when dialog Achild closed."));
await stepContext.Context.SendActivityAsync(MessageFactory.Text($""));
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"will close dialog A."));
return await stepContext.EndDialogAsync();
}
private static async Task<DialogTurnResult> ThirdStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
// what is the best way to end this?
// return await stepContext.ReplaceDialogAsync(InitialId);
return await stepContext.EndDialogAsync();
}
答案 0 :(得分:0)
除了your other issue中指出的问题外,是的,您正在正确地处理复杂的对话框。
通过精确地执行您的操作来管理复杂的对话框流要容易得多:拥有一个主要的对话框类,然后使用if
语句分支到其他对话框。您可能还需要考虑使用switch
语句,特别是如果您可能在两个以上的方向上分支。
Advanced dialog flow-一般准则
Creating reusable dialogs-一般准则
What each method of stepContext
does,与对话框相关-这样您就知道该调用什么来完成所需的操作
Prompt Validation Sample-必要时用于集成快速验证