如何在消息到达识别器之前拦截 FormFlow 中的消息? (枚举用法)

How do I intercept a message in FormFlow before it reaches recognizers? (enum usage)

如果用户不喜欢列表中的任何选项,我想拦截他写的内容。我的代码如下,但验证函数仅在用户选择一个选项时才起作用。

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;
        }
    }
}

有几个可能的解决方法供您考虑。通常,如果您想要考虑用户想问问题或说与表单无关的内容的情况,您会让他们使用 取消表单。如果您希望您的机器人足够聪明以解释用户何时在表单中间更改主题,那就更高级了。

如果您想继续使用验证方法,您可以将 MainOption 字段更改为 string 而不是 MainOptions?,以便所有用户输入都发送到验证方法,但随后您需要自己生成选项列表。

我的建议是使用自定义提示器而不是验证方法。当一条消息在 FormFlow 中不是有效选项时,我写了一个 blog post that details how to make such a prompter. First you would provide a NotUnderstood template 来向您的提示器指示。然后在提示符中调用 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;
    }
}