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;