我正在使用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中获取名称?
答案 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 post和a sample。
答案 1 :(得分:0)
你有一些更简单的选择 1)使您的字段可以为空,如果您从保存的机器人状态设置它们,默认情况下它们将被跳过。 (除非你传入FormOptions.PromptFieldsWithValues。) 2)将您的值转换为EntityRecommendations。如果它们与表单中的字段匹配,则也会分配和跳过它们。