2017-02-19 16 views
1

Я хочу получить доступ к userData из формы FormFlow. Единственный способ, которым я смог это сделать, - создать статический объект контекста в моем классе FormFlow public static IDialogContext context { get; set; }, как показано ниже.BotFramework Доступ к userData в потоке формы

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; 

Есть ли лучший способ сделать это?

+0

Отлично, я просто думал об этой же проблеме! –

ответ

2

Я думаю, что лучший способ сделать это - создать экземпляр FormDialog, используя new вместо метода FromForm. Таким образом, позволит отправить экземпляр состояния вида (в вашем случае Reservation), предварительно заполненные с любым значением у вас уже есть в государстве (например userName)

var form = new FormDialog<Reservation>(
       new Reservation(userName), 
       ReservationForm.BuildForm, 
       FormOptions.PromptInStart, 
       null); 

context.Call(form, this.ReservationFormComplete) 

Here образец делает только что ,

+1

Спасибо .. так просто я пропустил добавление конструктора в класс резервирования, чтобы передать контекст. –

+0

Отлично. Хотя настройка контекста определенно будет работать, преимущество отправки значений для свойств было бы лучше в том смысле, что FormFlow пропустит их, если свойство «state» имеет значение –

+0

Gotcha, поэтому просто выполните это. Имя = имя в конструкторе и сделать с ним. –

1

Благодаря Ezequiel Jadib, я думал, что разместил здесь все решение для других.

Итак, в RootDialog я создаю диалоговое окно, используя новое и передавая в контексте модели резервирования.

var form = new FormDialog<Reservation>(
new Reservation(context), 
ReservationForm.BuildForm, 
FormOptions.PromptInStart, 
null); 

В моем Reservation классе (My Model) Я добавил конструктор, который взял в объекте IDialogContext (и добавление using Microsfot.Bot.Build.Dialogs; к верхней) Создание свойства провести его с частным сеттера.

public class Reservation 
{ 
    public IDialogContext Context { get; private set; } 
    public Reservation(IDialogContext context) 
    { 
     this.Context = context; 
    } 

Я тогда в состоянии получить доступ весь мой контекст (USERDATA, ConversationData, и т.д ...) внутри formflow, чтобы проверить его и игнорировать вопросы, которые были бы повторить.

state.Context.UserData.TryGetValue<string>("Name", out userName); 
state.Name = userName;