0

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

我有一个 FormFlow 对话框,它收集用于保留表的信息。FormFlow 中的一项是询问名称。在另一个对话框中,我正在收集名称并将其保存到 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 中获取名称(如果存在)?

4

2 回答 2

0

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

于 2017-02-17T18:45:52.483 回答
0

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

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

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

我已经写了一篇简短的博客文章和一个关于您可能感兴趣的主题的示例。

于 2017-02-17T05:05:40.303 回答