我有一个问题......不幸的是,网络上的所有样本都太浅了,并没有很好地涵盖这一点:
我有一个扩展 LuisDialog 的 RootDialog。这个 RootDialog 负责弄清楚用户想要做什么。这可能是多件事,但其中之一将是启动新订单。为此,RootDialog 会将调用转发给 NewOrderDialog,NewOrderDialog 的职责是弄清楚一些基本细节(用户想要订购什么,他喜欢使用哪个地址),最后它会确认订购并返回到 RootDialog。
RootDialog 的代码非常简单:
[Serializable]
public class RootDialog : LuisDialog<object>
{
public RootDialog() : base(new LuisService(new LuisModelAttribute(ConfigurationManager.AppSettings["LuisAppId"], ConfigurationManager.AppSettings["LuisAPIKey"], domain: "westus.api.cognitive.microsoft.com")))
{
}
[LuisIntent("Order.Place")]
public async Task PlaceOrderIntent(IDialogContext context, LuisResult result)
{
await context.Forward(new NewOrderDialog(), OnPlaceOrderIntentCompleted, context.Activity, CancellationToken.None);
context.Wait(MessageReceived);
}
private async Task OnPlaceOrderIntentCompleted(IDialogContext context, IAwaitable<object> result)
{
await context.PostAsync("Your order has been placed. Thank you for shopping with us.");
context.Wait(MessageReceived);
}
}
我还为 NewOrderDialog 考虑了一些代码:
[Serializable]
public class NewOrderDialog : LuisDialog<object>
{
private string _product;
private string _address;
public NewOrderDialog() : base(new LuisService(new LuisModelAttribute(ConfigurationManager.AppSettings["LuisAppId"], ConfigurationManager.AppSettings["LuisAPIKey"], domain: "westus.api.cognitive.microsoft.com")))
{
}
[LuisIntent("Order.RequestedItem")]
public async Task RequestItemIntent(IDialogContext context, LuisResult result)
{
EntityRecommendation item;
if (result.TryFindEntity("Item", out item))
{
_product = item.Entity;
await context.PostAsync($"Okay, I understood you want to order: {_product}.");
}
else
{
await context.PostAsync("I couldn't understand what you would like to buy. Can you try it again?");
}
context.Wait(MessageReceived);
}
[LuisIntent("Order.AddedAddress")]
public async Task AddAddressIntent(IDialogContext context, LuisResult result)
{
EntityRecommendation item;
if (result.TryFindEntity("Address", out item))
{
_address = item.Entity;
await context.PostAsync($"Okay, I understood you want to ship the item to: {_address}.");
}
else
{
await context.PostAsync("I couldn't understand where you would like to ship the item. Can you try it again?");
}
context.Wait(MessageReceived);
}
}
列出的代码不起作用。进入 Order.Place 意图后,它立即执行“成功”回调,然后抛出此异常:
异常:IDialog 方法执行已通过 IDialogStack 指定的多个恢复处理程序完成。[“文本/纯文本”类型的文件]
所以我有几个问题:
- 如何解决我得到的错误?
- 我如何在进入 NewOrderDialog 时检查我们是否已经知道产品和地址是什么,如果没有提示他们输入正确的信息?
- 为什么即使我没有调用 context.Done() 之类的东西,NewOrderDialog 也会关闭?我只希望在收集完所有信息并确认订单后关闭它。