2017-02-16 8 views
0

Я использую C# SDK для BotBuilder для BotFramework и хочу сделать следующее.BotFramework Установка данных по умолчанию в FormFlow

У меня есть диалог FormFlow, который собирает информацию для резервирования таблицы. Один из элементов в FormFlow запрашивает имя. В другом диалоговом окне я собираю имя и сохраняю его в userData.

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

My 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); 

Как я могу иметь formflow пропустить поле имени и взять имя из USERDATA, если она существует?

ответ

0

Определить FieldReflector.SetActive для свойства Name. Например:

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

Затем в проверке SetFieldActive делегата, если имя уже существует, и если да, то установите значение в state и возвращать ложь. Тогда приглашение не будет показано. Если вы не найдете имя, верните true, чтобы отобразить приглашение.

Я написал a brief blog post и a sample об этой теме вы можете быть заинтересованы.

0

У вас есть какие-то более простые варианты.
1) Сделайте свои поля нулевыми, и если вы установите их из сохраненного состояния бота, по умолчанию они будут пропущены. (Если вы не проходите в FormOptions.PromptFieldsWithValues.) 2) Превратите свои значения в EntityRecommendations. Если они соответствуют полям в вашей форме, они будут назначены и пропущены.