如何在Bot Framework C#中使用Carousel Hero Card动作触发CallBack方法

时间:2018-01-15 05:49:51

标签: c# botframework

我正在研究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();
        }
    }

2 个答案:

答案 0 :(得分:0)

问题在于您是如何尝试呼叫您的孩子对话框RaiseTicket

首先,如果它是一个对话框,它应该实现IDialog接口。

然后,您必须将消息调用或转发到对话框。您不应手动调用StartAsync方法。

您可以阅读Handling multiple dialogs in Microsoft bot frameworkCalling 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);