1

在构建表单之前如何获取用户输入。例如,如果用户在表单流程中的任何时候键入“exit”,我想将用户输入保存到状态变量中并检查它是否等于“exit”,如果它确实返回 null 或执行一些代码。

namespace MyBot.Helpers
{

public enum Person
{

    //      [Describe("I am a Student")]
    IAmStudent,
    //    [Describe("I am an Alumni")]
    IAmAlumni,
    //  [Describe("Other")]
    Other

};
public enum HardInfo { Yes, No };

[Serializable]
public class FeedBackClass
{
    public bool AskToSpecifyOther = true;
    public string OtherRequest = string.Empty;


    [Prompt("May I Have Your Name?")]
    [Pattern(@"^[a-zA-Z ]*$")]
    public string Name { get; set; }
    [Prompt("What is your Email Address?")]
    public string Email { get; set; }

    [Prompt("Please Select From The Following? {||}")]
    [Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
    public Person? PersonType { get; set; }

    [Prompt("Please Specify Other? {||}")]
    public string OtherType { get; set; }

    [Prompt("Was The Information You Are Looking For Hard To Find? {||}")]
    [Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
    public HardInfo? HardToFindInfo { get; set; }

    public static IForm<FeedBackClass> MYBuildForm()
    {
        var status = "exit";
        if (status == null) {
            return null;
        }

        else
        {
            return new FormBuilder<FeedBackClass>()
                .Field(nameof(Name), validate: ValidateName)
                .Field(nameof(Email), validate: ValidateContactInformation)
                .Field(new FieldReflector<FeedBackClass>(nameof(PersonType))
                            .SetActive(state => state.AskToSpecifyOther)
                            .SetNext(SetNext))
                 .Field(nameof(OtherType), state => state.OtherRequest.Contains("oth"))
                 .Field(nameof(HardToFindInfo)).Confirm("Is this your selection?\n{*}")
                .OnCompletion(async (context, state) =>
                {
                    await context.PostAsync("Thanks for your feedback! You are Awsome!");
                    context.Done<object>(new object());

                })

                .Build();
        }
4

1 回答 1

1

如果用户在表单流期间的任何时候键入“exit”,我想将用户输入保存到状态变量中并检查它是否等于“exit”,如果它确实返回 null 或执行一些代码。

您似乎想实现全局处理程序来处理“退出”命令。Scorables 可以拦截每条发送到 Conversation 的消息,并根据您定义的逻辑对消息应用评分,这可以帮助您实现它,您可以尝试一下。

有关详细信息,请参阅使用 scorables 的全局消息处理程序或此全局消息处理程序示例

以下代码片段对我有用,您可以参考它。

退出对话框:

public class ExitDialog : IDialog<object>
{
    public async Task StartAsync(IDialogContext context)
    {
        await context.PostAsync("This is the Settings Dialog. Reply with anything to return to prior dialog.");

        context.Wait(this.MessageReceived);
    }

    private async Task MessageReceived(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
        var message = await result;

        if ((message.Text != null) && (message.Text.Trim().Length > 0))
        {
            context.Done<object>(null);
        }
        else
        {
            context.Fail(new Exception("Message was not a string or was an empty string."));
        }
    }
}

退出评分:

public class ExitScorable : ScorableBase<IActivity, string, double>
{
    private readonly IDialogTask task;

    public ExitScorable(IDialogTask task)
    {
        SetField.NotNull(out this.task, nameof(task), task);
    }

    protected override async Task<string> PrepareAsync(IActivity activity, CancellationToken token)
    {
        var message = activity as IMessageActivity;

        if (message != null && !string.IsNullOrWhiteSpace(message.Text))
        {
            if (message.Text.ToLower().Equals("exit", StringComparison.InvariantCultureIgnoreCase))
            {
                return message.Text;
            }
        }

        return null;
    }

    protected override bool HasScore(IActivity item, string state)
    {
        return state != null;
    }

    protected override double GetScore(IActivity item, string state)
    {
        return 1.0;
    }

    protected override async Task PostAsync(IActivity item, string state, CancellationToken token)
    {
        var message = item as IMessageActivity;

        if (message != null)
        {
            var settingsDialog = new ExitDialog();

            var interruption = settingsDialog.Void<object, IMessageActivity>();

            this.task.Call(interruption, null);

            await this.task.PollAsync(token);
        }
    }

    protected override Task DoneAsync(IActivity item, string state, CancellationToken token)
    {
        return Task.CompletedTask;
    }
}

GlobalMessageHandlersBot 模块:

public class GlobalMessageHandlersBotModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);

        builder
            .Register(c => new ExitScorable(c.Resolve<IDialogTask>()))
            .As<IScorable<IActivity, double>>()
            .InstancePerLifetimeScope();
    }
}

注册模块:

Conversation.UpdateContainer(
    builder =>
    {
        builder.RegisterModule(new ReflectionSurrogateModule());
        builder.RegisterModule<GlobalMessageHandlersBotModule>();
    });

测试结果:

在此处输入图像描述

于 2018-02-22T09:57:46.400 回答