我正在使用Botbuilder的C#SDK进行BotFrameWork,并想做以下操作。
我有一个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);
如果存在,我如何才能跳过名称字段并从用户数据中获取名称?
定义名称属性的fieldreflector.setactive。例如:
.Field(new FieldReflector<ReservationDialog>(nameof(ReservationDialog.Name))
.SetActive((state) => SetFieldActive(state, nameof(ReservationDialog.Name)))
...
然后在您的SetFieldActive
委托中检查名称是否已经存在,如果是,则将值设置为state
并返回false。然后不会显示提示。如果找不到名称,请返回true以显示提示。
我写了一篇简短的博客文章和您可能感兴趣的有关此主题的示例。
您有一些简单的选项。
1)使您的字段无效,如果您从保存的bot状态设置它们,则默认情况下会跳过。(除非您通过emoptions.promptfieldswithvalues。)2)将您的价值变成实体估算。如果它们以您的表格匹配字段,也将被分配和跳过。