BotFramework在FormFlow中设置默认数据

时间:2017-02-16 19:00:11

标签: c# botframework formflow

我正在使用BotBuilder的C#SDK进行BotFramework,并希望执行以下操作。

我有一个FormFlow对话框,用于收集保留表格的信息。 FormFlow中的一个项目是要求Name。在另一个对话框中,我收集名称并将其保存到userData。

context.UserData.SetValue<string>("Name", userName);

我的Formflow看起来像这样。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Bot.Builder.FormFlow;
using Microsoft.Bot.Builder.FormFlow.Advanced;
using System.Text.RegularExpressions;
using System.Threading.Tasks;


namespace DinnerBot.Dialogs
{   
    [Serializable]
    public class ReservationDialog
    {

        public enum SpecialOccasionOptions
        {
            Birthday,
            Anniversary,
            Engagement,
            none
        }

        [Prompt(new string[] { "What is your name?" })]
        public string Name { get; set; }

        [Prompt(new string[] { "What is your email?" })]
        public string Email { get; set; }

        [Pattern(@"^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$")]
        public string PhoneNumber { get; set; }

        [Prompt("What date would you like to dine with us? example: today, tomorrow, or any date like 04-06-2017 {||}", AllowDefault = BoolDefault.True)]
        [Describe("Reservation date, example: today, tomorrow, or any date like 04-06-2017")]
        public DateTime ReservationDate { get; set; }

        public DateTime ReservationTime { get; set; }

        [Prompt("How many people will be joining us?")]
        [Numeric(1, 20)]
        public int? NumberOfDinners;
        public SpecialOccasionOptions? SpecialOccasion;

        [Numeric(1, 5)]
        [Optional]
        [Describe("for how you enjoyed your experience with Dinner Bot today (optional)")]
        public double? Rating;

        public static IForm<ReservationDialog> BuildForm()
        {
            return new FormBuilder<ReservationDialog>()
                .Field(nameof(Name))
                .Field(nameof(Email), validate: ValidateContactInformation)
                .Field(nameof(PhoneNumber))
                .Field(nameof(ReservationDate))
                .Field(new FieldReflector<ReservationDialog>(nameof(ReservationDialog.ReservationTime))
                    .SetPrompt(PerLinePromptAttribute("What time would you like to arrive?"))
                    ).AddRemainingFields()
                .Build();
        }

        private static Task<ValidateResult> ValidateContactInformation(ReservationDialog state, object response)
        {
            var result = new ValidateResult();
            string contactInfo = string.Empty;
            if (GetEmailAddress((string)response, out contactInfo))
            {
                result.IsValid = true;
                result.Value = contactInfo;
            }
            else
            {
                result.IsValid = false;
                result.Feedback = "You did not enter valid email address.";
            }
            return Task.FromResult(result);
        }

        private static bool GetEmailAddress(string response, out string contactInfo)
        {
            contactInfo = string.Empty;
            var match = Regex.Match(response, @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");
            if (match.Success)
            {
                contactInfo = match.Value;
                return true;
            }
            return false;
        }

        private static PromptAttribute PerLinePromptAttribute(string pattern)
        {
            return new PromptAttribute(pattern)
            {
                ChoiceStyle = ChoiceStyleOptions.PerLine
            };
        }


    }
}

在我的根对话框中,我这样称呼它。

                        context.Call(FormDialog.FromForm<ReservationDialog>(ReservationDialog.BuildForm,
                        FormOptions.PromptInStart), this.ReservationFormComplete);

如何让表单流程跳过名称字段并从userData中获取名称?

2 个答案:

答案 0 :(得分:0)

为Name属性定义FieldReflector.SetActive。例如:

.Field(new FieldReflector<ReservationDialog>(nameof(ReservationDialog.Name))
    .SetActive((state) => SetFieldActive(state, nameof(ReservationDialog.Name)))
    ...

然后在SetFieldActive委托中检查名称是否已存在,如果存在,请将值设置为state并返回false。然后提示不会显示。如果找不到名称,则返回true以显示提示。

我已经就您可能感兴趣的这个主题撰写了a brief blog posta sample

答案 1 :(得分:0)

你有一些更简单的选择 1)使您的字段可以为空,如果您从保存的机器人状态设置它们,默认情况下它们将被跳过。 (除非你传入FormOptions.PromptFieldsWithValues。) 2)将您的值转换为EntityRecommendations。如果它们与表单中的字段匹配,则也会分配和跳过它们。