我需要根据活动对话框的ID来做一个条件。
var dc = await _dialogs.CreateContextAsync(turnContext);
if (dc.ActiveDialog != null && dc.ActiveDialog.id == "SkipLuisDialog")
{
var interruptedQnaMaker = await IsTurnInterruptedDispatchToQnAMakerAsync(turnContext, topDispatch, QnaConfiguration, cancellationToken);
}
当我像这样检查OnTurnAsync()
上的活动对话框时:
if (dc.ActiveDialog != null)
{
await dc.Context.SendActivityAsync(dc.ActiveDialog.Id.ToString());
}
它总是说“ mainDialog”,这是我的主对话框的ID。即使在“ FAQDialog”或“ complaintDialog”上输入即时消息,活动对话框的ID也始终为“ mainDialog”。为什么在FAQ对话框中的im时活动对话框ID不会更改为“ FAQDialog”,而在投诉对话框中的im则为什么活动对话框ID不会更改为“ complaintDialog”?
我的主对话框和其他对话框在另一个类中。
这就是我在OnTurnAsync()
上调用mainDialog的方式:
if (!dc.Context.Responded)
{
switch (dialogResult.Status)
{
case DialogTurnStatus.Empty:
switch (topIntent) // topIntent // text
{
case GetStartedIntent:
await dc.BeginDialogAsync(MainDialogId);
break;
case NoneIntent:
default:
await dc.Context.SendActivityAsync("I didn't understand what you just said to me.");
break;
}
break;
case DialogTurnStatus.Waiting:
// The active dialog is waiting for a response from the user, so do nothing.
break;
case DialogTurnStatus.Complete:
await dc.EndDialogAsync();
break;
default:
await dc.CancelAllDialogsAsync();
break;
}
}
主对话框:
namespace CoreBot.Dialogs
{ 公共类MainDialog:ComponentDialog { 私有常量字符串InitialId =“ mainDialog”; 私有常量字符串TextPromptId =“ textPrompt”;
private const string ComplaintDialogId = "complaintDialog";
private const string FAQDialogId = "FAQDialog";
public MainDialog(string dialogId) : base(dialogId)
{
WaterfallStep[] waterfallSteps = new WaterfallStep[]
{
FirstStepAsync,
SecondStepAsync,
ThirdStepAsync,
};
AddDialog(new WaterfallDialog(InitialId, waterfallSteps));
AddDialog(new FAQDialog(FAQDialogId));
AddDialog(new FileComplaintDialog(ComplaintDialogId));
AddDialog(new TextPrompt(TextPromptId));
}
private static async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
return await stepContext.PromptAsync(
TextPromptId,
new PromptOptions
{
Prompt = new Activity
{
Type = ActivityTypes.Message,
Text = $"What can i do for you?",
SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() { Title = "Frequently Asked Questions", Type = ActionTypes.ImBack, Value = "Frequently Asked Questions" },
new CardAction() { Title = "File a Complaint Ticket", Type = ActionTypes.ImBack, Value = "File a Complaint Ticket" },
},
},
},
});
}
private static async Task<DialogTurnResult> SecondStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
var response = stepContext.Result.ToString().ToLower();
string[] FAQArray = { "frequently asked questions", "question", "ask question" };
string[] ComplaintsArray = { "file a complaint ticket", "complaint", "file a complaint" };
if (FAQArray.Contains(response))
{
return await stepContext.BeginDialogAsync(FAQDialogId, cancellationToken);
}
if (ComplaintsArray.Contains(response))
{
await stepContext.EndDialogAsync();
return await stepContext.BeginDialogAsync(ComplaintDialogId, cancellationToken: cancellationToken);
}
return await stepContext.NextAsync();
}
private static async Task<DialogTurnResult> ThirdStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
return await stepContext.ReplaceDialogAsync(InitialId);
}
}
}
主对话框调用2个对话框。这就是其中之一。
namespace CoreBot.Dialogs
{
public class FAQDialog : ComponentDialog
{
private const string InitialId = "FAQDialog";
private const string ChoicePromptId = "choicePrompt";
private const string TextPromptId = "textPrompt";
private const string ConfirmPromptId = "confirmPrompt";
public FAQDialog(string dialogId) : base(dialogId)
{
WaterfallStep[] waterfallSteps = new WaterfallStep[]
{
FirstStepAsync,
SecondStepAsync,
ThirdStepAsync,
FourthStepAsync,
};
AddDialog(new WaterfallDialog(InitialId, waterfallSteps));
AddDialog(new ChoicePrompt(ChoicePromptId));
AddDialog(new ConfirmPrompt(ConfirmPromptId));
AddDialog(new TextPrompt(TextPromptId));
}
private static async Task<DialogTurnResult> FirstStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
var choices = new List<Choice>();
choices.Add(new Choice { Value = "This is Sample Question 1", Synonyms = new List<string> { "Question 1" } });
choices.Add(new Choice { Value = "This is Sample Question 2", Synonyms = new List<string> { "Question 2" } });
return await stepContext.PromptAsync(
ChoicePromptId,
new PromptOptions
{
Prompt = MessageFactory.Text($"Welcome to FAQ! Choose the number of the question or type your own question."),
Choices = choices,
});
}
private static async Task<DialogTurnResult> SecondStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
var choiceResult = (stepContext.Result as FoundChoice).Value.ToLower();
switch (choiceResult)
{
case "this is sample question 1":
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Answer to question 1."));
break;
case "this is sample question 2":
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Answer to question 2."));
break;
default:
break;
}
return await stepContext.NextAsync();
}
private static async Task<DialogTurnResult> ThirdStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
return await stepContext.PromptAsync(
ConfirmPromptId,
new PromptOptions
{
Prompt = MessageFactory.Text($"Have another question?"),
});
}
private static async Task<DialogTurnResult> FourthStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken = default(CancellationToken))
{
var confirmResult = (bool)stepContext.Result;
if (confirmResult)
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Ask away!"));
return await stepContext.ReplaceDialogAsync(InitialId);
}
else
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Great!"));
return await stepContext.EndDialogAsync();
}
}
}
}
答案 0 :(得分:1)
这是因为在MainDialog
中调用了所有对话框。
这里或多或少是怎么回事:
在MyBot.cs
(或您的主.cs
主文件中)中,您有类似Dialogs = new DialogSet(_dialogStateAccessor)
的内容,它将创建一个空对话框stack:
___________
然后,您使用类似await dc.BeginDialogAsync(MainDialogId);
的名称,它将MainDialog
添加到对话框堆栈的顶部:
______________
| MainDialog |
|______________|
如果您在MainDialog外部调用return await stepContext.BeginDialogAsync(FAQDialogId, cancellationToken);
,则堆栈将如下所示:
______________
| FAQDialogId |
|______________|
______________
| MainDialog |
|______________|
但是,您是从MainDialog内部调用return await stepContext.BeginDialogAsync(FAQDialogId, cancellationToken);
的,因此它是自己的堆栈,因此FAQDialog是MainDialog中的活动对话框,但是您的Dialogs
堆栈仍将MainDialog作为ActiveDialog。因此,您的堆栈或多或少是这样的:
_______________________
| ______________ |
| |__FAQDialog__| |
| |
| MainDialog |
|_______________________|
您有两种选择:
1。从MainDialog
外部调用所有其他对话框。
如果您不打算返回MainDialog
,则可以执行以下操作:
在MainDialog
中:
return await stepContext.EndDialogAsync("FAQDialog");
在MyBot.cs
中:
switch (dialogResult)
{
case "FAQDialog":
dc.BeginDialogAsync(FAQDialogId, cancellationToken);
break;
case "ComplaintDialog":
dc.BeginDialogAsync(ComplaintDialogId, cancellationToken);
break;
}
2。在ActiveDialog堆栈中挖出对话框的ID
if (dc.ActiveDialog != null && IsDialogInStack(dc.ActiveDialog, "SkipLuisDialog"))
{
var interruptedQnaMaker = await IsTurnInterruptedDispatchToQnAMakerAsync(turnContext, topDispatch, QnaConfiguration, cancellationToken);
}
[...]
private bool IsDialogInStack(DialogInstance activeDialog, string searchId)
{
if (activeDialog.Id == searchId)
{
return true;
};
foreach (KeyValuePair<string, object> item in activeDialog.State)
{
if (item.Key == "dialogs" && item.Value is DialogState)
{
DialogState dialogState = (DialogState)item.Value;
foreach (DialogInstance dialog in dialogState.DialogStack)
{
return IsDialogInStack(dialog, searchId);
}
}
}
return false;
}
注意:我不是C#专家,也许可以使用更好的方法来编写IsDialogInStack
,但是上面的代码可以正常工作。