代码之家  ›  专栏  ›  技术社区  ›  Loai Tayem

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

  •  1
  • Loai Tayem  · 技术社区  · 7 年前

    如何在构建表单之前获取用户输入。例如,如果用户在formflow期间的任何时候键入“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();
            }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Fei Han    7 年前

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

    似乎您希望实现全局处理程序来处理“exit”命令。Scorables可以截获发送到对话的每条消息,并根据您定义的逻辑对消息进行评分,这可以帮助您实现,您可以尝试一下。

    有关详细信息,请参阅 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."));
            }
        }
    }
    

    可退出:

    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