Microsoft Bot Framework Form Builder C#,在构建表单之前获取用户输入

时间:2018-02-21 16:29:09

标签: c# botframework chatbot formbuilder formflow

如何在构建表单之前获取用户输入。例如,如果用户在表单流中的任何时候键入“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();
        }

1 个答案:

答案 0 :(得分:1)

  

如果用户键入&#34;退出&#34;在表单流程中的任何时候,我想将用户输入保存到状态变量中并检查它是否等于&#34;退出&#34;如果是,则返回null或执行一些代码。

您似乎希望实现全局处理程序来处理&#34;退出&#34;命令。 Scorables可以拦截发送给Conversation的每条消息,并根据您定义的逻辑对消息应用分数,这可以帮助您实现它,您可以尝试。

有关详细信息,请参阅Global message handlers using scorables或此Global Message Handlers Sample

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

<强> ExitDialog:

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."));
        }
    }
}

<强> ExitScorable:

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

<强> GlobalMessageHandlersBotModule:

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

测试结果:

enter image description here