C# BotFramework在FormFlow中设置默认数据
我将BotBuilder的C#SDK用于BotFramework,并希望执行以下操作 我有一个FormFlow对话框,用于收集预订表的信息。FormFlow中的一项是询问名称。在另一个对话框中,我收集名称并将其保存到userDataC# BotFramework在FormFlow中设置默认数据,c#,botframework,formflow,C#,Botframework,Formflow,我将BotBuilder的C#SDK用于BotFramework,并希望执行以下操作 我有一个FormFlow对话框,用于收集预订表的信息。FormFlow中的一项是询问名称。在另一个对话框中,我收集名称并将其保存到userData context.UserData.SetValue<string>("Name", userName); context.UserData.SetValue(“名称”,用户名); 我的Formflow看起来像这样 using System; usin
context.UserData.SetValue<string>("Name", userName);
context.UserData.SetValue(“名称”,用户名);
我的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
};
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用Microsoft.Bot.Builder.FormFlow;
使用Microsoft.Bot.Builder.FormFlow.Advanced;
使用System.Text.RegularExpressions;
使用System.Threading.Tasks;
名称空间DinnerBot.Dialogs
{
[可序列化]
公共类保留对话框
{
公共枚举特殊位置选项
{
生日,
周年纪念,
订婚,
没有一个
}
[提示(新字符串[]{“您叫什么名字?”}]
公共字符串名称{get;set;}
[提示(新字符串[]{“您的电子邮件是什么?”}]
公共字符串电子邮件{get;set;}
[模式(@“^(+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$”)
公共字符串PhoneNumber{get;set;}
[提示(“您想在哪一天与我们共进晚餐?例如:今天、明天或任何日期,如2017年6月4日{|}”,AllowDefault=BoolDefault.True)]
[描述(“预订日期,例如:今天、明天或任何日期,如2017年6月4日”)]
公共日期时间保留日期{get;set;}
公共日期时间保留时间{get;set;}
[提示(“有多少人将加入我们?”)]
[数字(1,20)]
公共晚餐的数量;
公共特殊场所选择?特殊场所选择;
[数字(1,5)]
[可选]
[描述(“您如何享受今天的晚餐机器人体验(可选)”]
公众双重评级;
公共静态表单BuildForm()
{
返回新的FormBuilder()
.字段(名称)
.字段(名称(电子邮件),验证:ValidateContactInformation)
.字段(姓名(电话号码))
.字段(名称(预订日期))
.Field(新的FieldReflector(名称(ReservationDialog.ReservationTime))
.SetPrompt(PerLinePromptAttribute(“您希望什么时候到达?”)
).AddRemainingFields()
.Build();
}
私有静态任务ValidateContactInformation(保留对话框状态,对象响应)
{
var result=new ValidateResult();
string contactInfo=string.Empty;
if(GetEmailAddress((字符串)响应,out contactInfo))
{
result.IsValid=true;
结果。值=联系人信息;
}
其他的
{
result.IsValid=false;
result.Feedback=“您没有输入有效的电子邮件地址。”;
}
返回Task.FromResult(结果);
}
私有静态bool GetEmailAddress(字符串响应、字符串外联系人信息)
{
contactInfo=string.Empty;
var match=Regex.match(响应,“[a-z0-9!#$%&'*+/=?(?:\.[a-z0-9!#$%&'*+/=?”([a-z0-9])(?:[a-z0-9-]*[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])+[a-z0-9](?:[a-z0-9-*];
如果(匹配成功)
{
contactInfo=match.Value;
返回true;
}
返回false;
}
私有静态PrompAttribute PerlinePrompAttribute(字符串模式)
{
返回新的PrompAttribute(模式)
{
ChoiceStyle=ChoiceStyleOptions.PerLine
};
}
}
}
在我的根对话框中,我这样称呼它
context.Call(FormDialog.FromForm<ReservationDialog>(ReservationDialog.BuildForm,
FormOptions.PromptInStart), this.ReservationFormComplete);
context.Call(FormDialog.FromForm(ReservationDialog.BuildForm,
FormOptions.PromptInStart),此.ReservationFormComplete);
如何让formflow跳过name字段并从userData(如果存在)中获取名称?为name属性定义。例如:
.Field(new FieldReflector<ReservationDialog>(nameof(ReservationDialog.Name))
.SetActive((state) => SetFieldActive(state, nameof(ReservationDialog.Name)))
...
.Field(新的FieldReflector(Name of(ReservationDialog.Name))
.SetActive((state)=>SetFieldActive(state,nameof(ReservationDialog.Name)))
...
然后在SetFieldActive
委托中检查名称是否已存在,如果已存在,则将值设置为状态
,并返回false。然后将不显示提示。如果未找到名称,则返回true以显示提示
我已经写了很多关于这个主题的文章,你可能会感兴趣。你有一些更简单的选择。
1) 将字段设置为空,如果从保存的bot状态设置字段,则默认情况下将跳过这些字段。(除非您传入FormOptions.PromptFieldsWithValues。) 2) 将您的值转换为EntityRecommendations。如果它们与表单中的字段匹配,它们也将被分配和跳过