如果用户不喜欢列表中的任何选项,我想拦截用户写的内容。我的代码如下,但验证函数仅在用户选择一个选项时才有效。
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.FormFlow;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BotApplication.App_Code
{
public enum MainOptions { AccessoAreaRiservata = 1, AcquistoNuovaPolizza, RinnovoPolizza, Documenti, StatoPratica, AltroArgomento }
[Serializable]
public class MainReq
{
[Prompt("Indicare la tipologia della richiesta? {||}")]
public MainOptions? MainOption;
public static IForm<MainReq> BuildForm()
{
var form = (new FormBuilder<MainReq>()
.Field(nameof(MainOption),validate: async (state, response) =>
{
var result = new ValidateResult { IsValid = true };
{
string risposta = (response.ToString());
if (risposta == "AltroArgomento")
{
result.Feedback = "it works only if user choose an option";
result.IsValid = true;
}
return result;
}
})
.Build());
return form;
}
}
}
有几种可能的解决方法供您考虑。通常,如果要考虑用户想要提出问题或说出与表单无关的内容的情况,则可以让他们使用 Quit 命令取消表单。如果希望机器人足够智能,以便在用户在窗体中间更改主题时进行解释,那就更高级了。
如果要继续使用验证方法,可以将 MainOption 字段更改为string
而不是MainOptions?
,以便将所有用户输入发送到验证方法,但随后您需要自己生成选项列表。
我的建议是使用自定义提示器而不是验证方法。我写了一篇博客文章,详细介绍了如何制作这样的提示器。首先,您将提供一个 NotUnderstood 模板,以便在消息在 FormFlow 中不是有效选项时向提示者指示。然后在提示器中,您可以调用 QnAMaker 对话框或对消息执行任何操作。
// Define your NotUnderstood template
[Serializable, Template(TemplateUsage.NotUnderstood, NOT_UNDERSTOOD)]
public class MainReq
{
public const string NOT_UNDERSTOOD = "Not-understood message";
[Prompt("Indicare la tipologia della richiesta? {||}")]
public MainOptions? MainOption;
public static IForm<MainReq> BuildForm()
{
var form = (new FormBuilder<MainReq>()
.Prompter(PromptAsync) // Build your form with a custom prompter
.Build());
return form;
}
private static async Task<FormPrompt> PromptAsync(IDialogContext context, FormPrompt prompt, MainReq state, IField<MainReq> field)
{
var preamble = context.MakeMessage();
var promptMessage = context.MakeMessage();
if (prompt.GenerateMessages(preamble, promptMessage))
{
await context.PostAsync(preamble);
}
// Here is where we've made a change to the default prompter.
if (promptMessage.Text == NOT_UNDERSTOOD)
{
// Access the message the user typed with context.Activity
await context.PostAsync($"Do what you want with the message: {context.Activity.AsMessageActivity()?.Text}");
}
else
{
await context.PostAsync(promptMessage);
}
return prompt;
}
}