我正在研究BOT框架(C#),我面临一个问题,需要你的帮助。 下面的代码用于显示Hero卡的轮播和选择一个Hero Card我想调用一个回调方法,在下面的例子中你可以看到 OnCardSelection 是我要调用的方法卡选择,但执行行 context.Wait(onCardSelection)我收到以下错误
无效需要:预期呼叫,等待
可能是因为它正在结束对话并考虑采取进一步行动(点击Hero卡)作为新对话。 另外,我想在 OnCardSelection 方法中访问该卡的详细信息。 如何实现这一目标。 谢谢。
[LuisModel("your sub key", "secret")]
[Serializable]
public class BotManager : LuisDialog<object>
{
public async Task RaiseTicket(IDialogContext context, LuisResult result)
{
PromptDialog.Confirm(
context: context,
resume: ResumeAndHandleConfirmRaiseTicketAsync,
prompt: "It looks like you want to raise a ticket. Do you want to continue?",
retry: "I didn't understand. Please try again.");
}
private async Task ResumeAndHandleConfirmRaiseTicketAsync(IDialogContext context, IAwaitable<bool> argument)
{
bool choicesAreCorrect = await argument;
if (choicesAreCorrect)
{
RaiseTicket objRaiseTicket = new RaiseTicket();
await objRaiseTicket.StartAsync(context);
}
else
{
await context.PostAsync("Okay");
}
}
}
[Serializable]
public class RaiseTicket
{
public async Task StartAsync(IDialogContext context)
{
TypeOfTicket typeOfTicket;
context.UserData.TryGetValue("TypeOfTicket", out typeOfTicket);
if (typeOfTicket == TypeOfTicket.None)
{
//RaiseTicket
}
else
{
await PickExactCategory(context);
}
}
public async Task PickExactCategory(IDialogContext context)
{
var message = context.MakeMessage();
message.AttachmentLayout = AttachmentLayoutTypes.Carousel;
message.Attachments = GetCardsAttachments(categoryList);
await context.PostAsync(message);
context.Wait(OnCardSelection);
}
protected async Task OnCardSelection(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var answer = await result;
context.Done(new object());
}
private IList<Attachment> GetCardsAttachments(Categorylist[] categoryList)
{
List<Attachment> lstAttachment = new List<Attachment>();
foreach (Categorylist item in categoryList)
{
lstAttachment.Add(GetHeroCard(
item.Title, item.SubTitle,item.Text,
new CardAction(ActionTypes.ImBack, "Select", value: item.Tier3)));
}
return lstAttachment;
}
private static Attachment GetHeroCard(string title, string subtitle, string text, CardAction cardAction)
{
var heroCard = new HeroCard
{
Title = title,
Subtitle = subtitle,
Text = text,
Buttons = new List<CardAction>() { cardAction },
};
return heroCard.ToAttachment();
}
}
答案 0 :(得分:0)
问题在于您是如何尝试呼叫您的孩子对话框RaiseTicket
。
首先,如果它是一个对话框,它应该实现IDialog
接口。
然后,您必须将消息调用或转发到对话框。您不应手动调用StartAsync
方法。
您可以阅读Handling multiple dialogs in Microsoft bot framework或Calling Forms from Dialogs,了解Call
/ Forward
方法的更多工作原理。另外,您可以查看文档中的Manage conversation flow with dialogs文章。
答案 1 :(得分:0)
正如Ezequiel Jadib所说,问题是你如何调用RaiseTicket
,而RaiseTicket
应该实现IDialog
接口。
您可以修改RaiseTicket
,例如:
[Serializable]
public class RaiseTicket: IDialog<object>
{
public Task StartAsync(IDialogContext context)
{
context.Wait(PickExactCategory);
return Task.CompletedTask;
}
public async Task PickExactCategory(IDialogContext context, IAwaitable<object> result)
{
var message = context.MakeMessage();
message.AttachmentLayout = AttachmentLayoutTypes.Carousel;
message.Attachments = GetCardsAttachments(categoryList);
await context.PostAsync(message);
context.Wait(OnCardSelection);
}
public async Task OnCardSelection(IDialogContext context, IAwaitable<object> result)
{
var answer = await result as IMessageActivity;
context.Done(new object());
}
private IList<Attachment> GetCardsAttachments(List<Categorylist> categoryList)
{
List<Attachment> lstAttachment = new List<Attachment>();
foreach (Categorylist item in categoryList)
{
lstAttachment.Add(GetHeroCard(
item.Title, item.SubTitle, item.Text,
new CardAction(ActionTypes.ImBack, "Select", value: item.Tier3)));
}
return lstAttachment;
}
private static Attachment GetHeroCard(string title, string subtitle, string text, CardAction cardAction)
{
var heroCard = new HeroCard
{
Title = title,
Subtitle = subtitle,
Text = text,
Buttons = new List<CardAction>() { cardAction },
};
return heroCard.ToAttachment();
}
}
然后在RaiseTicket
中调用此BotManager
对话框,例如:
var dialog = new RaiseTicket();
await context.Forward(dialog, dialog.OnCardSelection, null, CancellationToken.None);