我的机器人会收到一些用户信息,例如订单号,以及基于搜索订单的其他一些细节。如果返回的订单超过1个,则会要求用户提供更多信息,以便提供2个额外的详细信息。
现在我的问题是因为我已经使用FormBuilder构建了表单并且在完成时我要求用户提供更多信息,以便应该是要求其他信息的方法。我应该创建另一个表单并请求信息,还是有办法在完成方法中将其他字段添加到同一表单。
我想在初始搜索完成后要求更多用户输入,并显示超过1个订单的msg。
作为我的属性SubOrderNumber& SubOrderVersion在OrderQuery类中,所以我应该为OrderQuery构建新表单还是有其他方法将这两个表单添加到现有的Order表单。
using System;
using Microsoft.Bot.Builder.FormFlow;
namespace Bot
{
[Serializable]
public class OrderSearchQuery
{
[Prompt("Please enter {&}")]
public string OrderNumber { get; set; }
[Prompt("Please enter {&}?")]
public String Location { get; set; }
[Prompt("Please provide last status {&}?")]
public string Status{ get; set; }
[Prompt("Please enter {&}?")]
public string SubOrderNumber { get; set; }
[Prompt("Please enter {&}?")]
public string SubOrderVersion { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.FormFlow;
using Microsoft.Bot.Connector;
namespace Bot.Dialogs
{
[Serializable]
public class OrderDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("Welcome to the Order helper!");
var orderFormDialog = FormDialog.FromForm(this.BuildOrderForm, FormOptions.PromptInStart);
context.Call(orderFormDialog, this.ResumeAfterOrdersFormDialog);
}
private IForm<OrderSearchQuery> BuildOrderForm()
{
OnCompletionAsyncDelegate<OrderSearchQuery> processOrderSearch = async (context, state) =>
{
await context.PostAsync($"Ok. Searching for Orders with Number: {state.OrderNumber}...");
};
return new FormBuilder<OrderSearchQuery>()
.Field(nameof(OrderSearchQuery.OrderNumber))
.AddRemainingFields(new string[] { nameof(RequiredDWPSearchQuery.SubOrderNumber), nameof(RequiredDWPSearchQuery.SubOrderVersion) })
.OnCompletion(processOrderSearch)
.Build();
}
private async Task ResumeAfterOrdersFormDialog(IDialogContext context, IAwaitable<OrderSearchQuery> result)
{
try
{
var searchQuery = await result;
await context.PostAsync($"I found total of 100 Ordes");
await context.PostAsync($"To get Order details, you will need to provide more info...");
}
catch (FormCanceledException ex)
{
string reply;
if (ex.InnerException == null)
{
reply = "You have canceled the operation. Quitting from the Required DWP Search";
}
else
{
reply = $"Oops! Something went wrong :( Technical Details: {ex.InnerException.Message}";
}
await context.PostAsync(reply);
}
finally
{
context.Done<object>(null);
}
}
}
}
答案 0 :(得分:0)
虽然有字段的条件参数和在验证中做逻辑的可能性,但我认为这不是最干净的方法。我会采取两种对话方式。
这是原始表单,删除了其他参数:
using Microsoft.Bot.Builder.FormFlow;
using System;
namespace TestChatbot.Dialogs
{
[Serializable]
public class OrderSearchQuery
{
[Prompt("Please enter {&}")]
public string OrderNumber { get; set; }
[Prompt("Please enter {&}?")]
public String Location { get; set; }
[Prompt("Please provide last status {&}?")]
public string Status { get; set; }
}
}
相反,我将其他属性移动到新表单:
using Microsoft.Bot.Builder.FormFlow;
using System;
namespace TestChatbot.Dialogs
{
[Serializable]
public class OrderFollowUp
{
[Prompt("Please enter {&}?")]
public string SubOrderNumber { get; set; }
[Prompt("Please enter {&}?")]
public string SubOrderVersion { get; set; }
}
}
然后我添加逻辑来处理第二种形式,具体取决于搜索结果:
using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.FormFlow;
namespace TestChatbot.Dialogs
{
[Serializable]
public class RootDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("Welcome to the Order helper!");
var orderFormDialog = FormDialog.FromForm(this.BuildOrderForm, FormOptions.PromptInStart);
context.Call(orderFormDialog, this.ResumeAfterOrdersFormDialog);
}
private IForm<OrderSearchQuery> BuildOrderForm()
{
return new FormBuilder<OrderSearchQuery>()
.Build();
}
private IForm<OrderFollowUp> BuildFollowUpForm()
{
return new FormBuilder<OrderFollowUp>()
.Build();
}
private async Task ResumeAfterOrdersFormDialog(IDialogContext context, IAwaitable<OrderSearchQuery> result)
{
try
{
var searchQuery = await result;
await context.PostAsync($"Ok. Searching for Orders with Number: {searchQuery.OrderNumber}...");
await context.PostAsync($"I found total of 100 Ordes");
int searchResultCount = 2;
if (searchResultCount > 1)
{
await context.PostAsync($"To get Order details, you will need to provide more info...");
var followUpDialog = FormDialog.FromForm(this.BuildFollowUpForm, FormOptions.PromptInStart);
context.Call(followUpDialog, this.ResumeAfterFollowUpDialog);
}
}
catch (FormCanceledException ex)
{
string reply;
if (ex.InnerException == null)
{
reply = "You have canceled the operation. Quitting from the Required DWP Search";
}
else
{
reply = $"Oops! Something went wrong :( Technical Details: {ex.InnerException.Message}";
}
await context.PostAsync(reply);
}
}
private async Task ResumeAfterFollowUpDialog(IDialogContext context, IAwaitable<OrderFollowUp> result)
{
await context.PostAsync($"Order complete.");
context.Done<object>(null);
}
}
}
这里的不同之处在于我在第一个对话框完成后删除了OnCompletion调用并在恢复处理程序上处理了该逻辑。根据搜索结果,您可以调用第二个对话框,就像您第一个提取其他信息一样。