2016-10-31 8 views
3

У меня есть subdialog в бот построен с использованием фреймворка бот MS, который начинается следующим образом - стандартный способ:был Дифференцировать ли IDialog вызывается с помощью context.Call() или context.Forward() в Microsoft Bot Framework

public async Task StartAsync(IDialogContext context) 
    { 
     var msg = "Let's find your flights! Tell me the flight number, city or airline."; 
     var reply = context.MakeMessage(); 
     reply.Text = msg; 
     //add quick replies here 
     await context.PostAsync(reply); 
     context.Wait(UserInputReceived); 
    } 

Этот диалог называется двумя разными способами, в зависимости от того, нажал ли пользователь на предыдущем экране кнопку «Полеты» или сразу же вошел номер рейса. Вот код из диалога родительского:

else if (response.Text == MainOptions[2]) //user tapped a button 
{ 
    context.Call(new FlightsDialog(), ChildDialogComplete); 
} 
else //user entered some text instead of tapping a button 
{ 
    await context.Forward(new FlightsDialog(), ChildDialogComplete, 
          activity, CancellationToken.None); 
} 

Вопрос: как я могу знать (изнутри FlightsDialog) был вызван ли, что диалог с использованием context.Call() или context.Forward()? Это связано с тем, что в случае context.Forward()StartAsync() не должен выводить приглашение с просьбой ввести номер рейса - они уже сделали это.

Лучшая идея заключается в том, чтобы сохранить флаг в ConversationData или данные пользователя, как показано ниже, и получить к нему доступ из IDialog, но я думал, что может быть лучший способ?

public static void SetUserDataProperty(Activity activity, string PropertyName, string ValueToSet) 
{ 
    StateClient client = activity.GetStateClient(); 
    BotData userData = client.BotState.GetUserData(activity.ChannelId, activity.From.Id); 
    userData.SetProperty<string>(PropertyName, ValueToSet); 
    client.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData); 
} 
+0

Я думаю, еще один способ сделать это, чтобы отправить что-то в конструкторе диалога. –

ответ

3

К сожалению Forward фактически вызывает Call (а затем делает некоторые другие вещи впоследствии), так что ваш диалог не будет иметь возможность дифференцировать.

void IDialogStack.Call<R>(IDialog<R> child, ResumeAfter<R> resume) 
{ 
    var callRest = ToRest(child.StartAsync); 
    if (resume != null) 
    { 
     var doneRest = ToRest(resume); 
     this.wait = this.fiber.Call<DialogTask, object, R>(callRest, null, doneRest); 
    } 
    else 
    { 
     this.wait = this.fiber.Call<DialogTask, object>(callRest, null); 
    } 
} 

async Task IDialogStack.Forward<R, T>(IDialog<R> child, ResumeAfter<R> resume, T item, CancellationToken token) 
{ 
    IDialogStack stack = this; 
    stack.Call(child, resume); 
    await stack.PollAsync(token); 
    IPostToBot postToBot = this; 
    await postToBot.PostAsync(item, token); 
} 

От https://github.com/Microsoft/BotBuilder/blob/10893730134135dd4af4250277de8e1b980f81c9/CSharp/Library/Dialogs/DialogTask.cs#L196