BotFramework 在表单流中访问用户数据
BotFramework Accessing userData within Form Flow
我想从 formFlow 表单中访问 userData。我能够做到的唯一方法是在我的 FormFlow class public static IDialogContext context { get; set; }
上创建一个静态上下文对象,如下所示。
public static IDialogContext context { get; set; }
public static IForm<Reservation> BuildForm()
{
string userName = String.Empty;
context.UserData.TryGetValue<string>("Name", out userName);
return new FormBuilder<Reservation>()
.Field(new FieldReflector<Reservation>(nameof(Reservation.Name))
.SetActive((state) =>
{
//StateClient stateClient = activity.GetStateClient();
//BotData userData = stateClient.BotState.GetUserDataAsync(activity.ChannelId, activity.From.Id);
state.Name = userName;
return String.IsNullOrEmpty(state.Name);
然后在我的 RootDialog 中,我在调用表单之前设置它。
case ReservationOption:
ReservationForm.context = context;
context.Call(FormDialog.FromForm<Reservation>(ReservationForm.BuildForm,
FormOptions.PromptInStart), this.ReservationFormComplete);
break;
有更好的方法吗?
我认为更好的方法是使用 new
而不是 FromForm
方法来实例化 FormDialog
。这样,将允许您发送表单状态的实例(在您的情况下 Reservation
)pre-filled 以及您在状态中已有的任何值(例如 userName
)
var form = new FormDialog<Reservation>(
new Reservation(userName),
ReservationForm.BuildForm,
FormOptions.PromptInStart,
null);
context.Call(form, this.ReservationFormComplete)
Here 就是一个例子。
感谢 Ezequiel Jadib,我想我会 post 为其他人提供整个解决方案。
所以在 RootDialog 中,我使用 new 实例化对话框并将上下文传递给预订模型。
var form = new FormDialog<Reservation>(
new Reservation(context),
ReservationForm.BuildForm,
FormOptions.PromptInStart,
null);
在我的预订 Class(我的模型)中,我添加了一个接受 IDialogContext 对象的构造函数(并在顶部添加了一个 using Microsfot.Bot.Build.Dialogs;
)创建一个 属性 来保存它与私人 setter。
public class Reservation
{
public IDialogContext Context { get; private set; }
public Reservation(IDialogContext context )
{
this.Context = context;
}
然后我可以从表单流内部访问我的整个上下文(userData、ConversationData 等...)以检查它并忽略会重复的问题。
state.Context.UserData.TryGetValue<string>("Name", out userName);
state.Name = userName;
我想从 formFlow 表单中访问 userData。我能够做到的唯一方法是在我的 FormFlow class public static IDialogContext context { get; set; }
上创建一个静态上下文对象,如下所示。
public static IDialogContext context { get; set; }
public static IForm<Reservation> BuildForm()
{
string userName = String.Empty;
context.UserData.TryGetValue<string>("Name", out userName);
return new FormBuilder<Reservation>()
.Field(new FieldReflector<Reservation>(nameof(Reservation.Name))
.SetActive((state) =>
{
//StateClient stateClient = activity.GetStateClient();
//BotData userData = stateClient.BotState.GetUserDataAsync(activity.ChannelId, activity.From.Id);
state.Name = userName;
return String.IsNullOrEmpty(state.Name);
然后在我的 RootDialog 中,我在调用表单之前设置它。
case ReservationOption:
ReservationForm.context = context;
context.Call(FormDialog.FromForm<Reservation>(ReservationForm.BuildForm,
FormOptions.PromptInStart), this.ReservationFormComplete);
break;
有更好的方法吗?
我认为更好的方法是使用 new
而不是 FromForm
方法来实例化 FormDialog
。这样,将允许您发送表单状态的实例(在您的情况下 Reservation
)pre-filled 以及您在状态中已有的任何值(例如 userName
)
var form = new FormDialog<Reservation>(
new Reservation(userName),
ReservationForm.BuildForm,
FormOptions.PromptInStart,
null);
context.Call(form, this.ReservationFormComplete)
Here 就是一个例子。
感谢 Ezequiel Jadib,我想我会 post 为其他人提供整个解决方案。
所以在 RootDialog 中,我使用 new 实例化对话框并将上下文传递给预订模型。
var form = new FormDialog<Reservation>(
new Reservation(context),
ReservationForm.BuildForm,
FormOptions.PromptInStart,
null);
在我的预订 Class(我的模型)中,我添加了一个接受 IDialogContext 对象的构造函数(并在顶部添加了一个 using Microsfot.Bot.Build.Dialogs;
)创建一个 属性 来保存它与私人 setter。
public class Reservation
{
public IDialogContext Context { get; private set; }
public Reservation(IDialogContext context )
{
this.Context = context;
}
然后我可以从表单流内部访问我的整个上下文(userData、ConversationData 等...)以检查它并忽略会重复的问题。
state.Context.UserData.TryGetValue<string>("Name", out userName);
state.Name = userName;