2017-08-11 42 views
2

我正在开发使用MS Bot Framework和LUIS的bot,并且在对话流程中有很多带有按钮的自适应卡片。我需要一种方法来处理这个流程的按钮(Action.Submit按钮是精确的)。在LuisIntent方法中处理自适应卡片按钮

我第一次尝试:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity) 
{ 
    if (activity.Type == ActivityTypes.Message) 
    { 
     if (activity.Text != null & activity.Value == null) 
     { 
      await Conversation.SendAsync(activity,() => new RootLuisDialog()); 
     } 
     else if (activity.Text == null & activity.Value != null) 
     { 
     await Conversation.SendAsync(activity,() => new ButtonHandler()); 
     } 
    } 
    else 
    { 
     this.HandleSystemMessage(activity); 
    } 

    var response = Request.CreateResponse(HttpStatusCode.OK); 
    return response; 
} 

因为被点击的自适应卡上的按钮时activity.Value包含Action.Submit按钮的属性。

这个想法是能够分开按钮控制器和RootLuisDialog()意向控制器。但它不起作用,我不知道为什么:通过此代码,总是会出现RootLuisDialog()退出。换句话说,在对话框内停留RootLuisDialog()

二的想法是用None路易斯意图,像这样:

[LuisIntent("")] 
    [LuisIntent("None")] 
    public async Task None(IDialogContext context, LuisResult result) 
    { 
     var act = context.Activity as IMessageActivity; 
     string message = String.Empty; 
     if (act.Text != null & act.Value == null) 
     { 
      message = $"Sorry, I did not understand '{act.Text}'. Type 'help' if you need assistance."; 
     } 
     else if (act.Text == null & act.Value != null) 
     { 
      Button btn = JsonConvert.DeserializeObject<Button>(act.Value.ToString()); 
      message = $"You clicked on {btn.Type}"; 
     } 
     await context.PostAsync(message); 

     context.Wait(this.MessageReceived); 
    } 

虽然这个工作,它看起来不正确下None意图是推动按钮的代码。

我也试过context.Wait(buttonHandler)其中buttonHandler是一个异步函数来处理按钮按下,但后来我得到这个错误信息:

"exceptionMessage": "Object reference not set to an instance of an object.", 
    "exceptionType": "System.NullReferenceException", 

我相信什么,我试图实现有一个相当好的答案,但这是我的第一个C#项目/任务,我需要帮助来完成这个排序。 非常感谢提前!

回答

2

我认为,更好的设计,如果你想在按钮的处理从LUIS意图分开,可以是具有RootDialog,做3两件事:

  1. 检查传入活动
  2. 如果activity.Value为空,然后将活动转发给LuisDialog(使用context.Forward。假设您想要检查所有消息为1),那么在执行逻辑context.Done(而不是context.Wait(...))之后,您必须“结束”LUIS对话框,
  3. 如果activity.Value不为空,则可以在RootDialog中处理消息并以context.Wait(...)结束;