コード例 #1
0
        private async Task <DialogTurnResult> RunStepAsync(DialogContext dc, int index, DialogReason reason, object result, CancellationToken cancellationToken)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            if (index < _steps.Count)
            {
                // Update persisted step index
                var state = dc.ActiveDialog.State;
                state[StepIndex] = index;

                // Create step context
                var options     = state[PersistedOptions];
                var values      = (IDictionary <string, object>)state[PersistedValues];
                var stepContext = new WaterfallStepContext(this, dc, options, values, index, reason, result);

                // Execute step
                return(await OnStepAsync(stepContext, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                // End of waterfall so just return any result to parent
                return(await dc.EndDialogAsync(result).ConfigureAwait(false));
            }
        }
コード例 #2
0
        /// <summary>
        /// Called when a child dialog on the parent's dialog stack completed this turn, returning
        /// control to this dialog component.
        /// </summary>
        /// <param name="outerDc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
        /// <param name="reason">Reason why the dialog resumed.</param>
        /// <param name="result">Optional, value returned from the dialog that was called. The type
        /// of the value returned is dependent on the child dialog.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        /// <remarks>If the task is successful, the result indicates whether this dialog is still
        /// active after this dialog turn has been processed.
        ///
        /// Generally, the child dialog was started with a call to
        /// <see cref="BeginDialogAsync(DialogContext, object, CancellationToken)"/> in the parent's
        /// context. However, if the
        /// <see cref="DialogContext.ReplaceDialogAsync(string, object, CancellationToken)"/> method
        /// is called, the logical child dialog may be different than the original.
        ///
        /// If this method is *not* overridden, the dialog automatically calls its
        /// <see cref="RepromptDialogAsync(ITurnContext, DialogInstance, CancellationToken)"/> when
        /// the user replies.
        /// </remarks>
        /// <seealso cref="RepromptDialogAsync(ITurnContext, DialogInstance, CancellationToken)"/>
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (result is CancellationToken)
            {
                throw new ArgumentException($"{nameof(result)} cannot be a cancellation token");
            }

            await EnsureInitializedAsync(outerDc).ConfigureAwait(false);

            await this.CheckForVersionChangeAsync(outerDc).ConfigureAwait(false);

            // Containers are typically leaf nodes on the stack but the dev is free to push other dialogs
            // on top of the stack which will result in the container receiving an unexpected call to
            // dialogResume() when the pushed on dialog ends.
            // To avoid the container prematurely ending we need to implement this method and simply
            // ask our inner dialog stack to re-prompt.
            await RepromptDialogAsync(outerDc.Context, outerDc.ActiveDialog, cancellationToken).ConfigureAwait(false);

            return(Dialog.EndOfTurn);
        }
コード例 #3
0
 /// <summary>
 /// Called when the dialog is ending.
 /// </summary>
 /// <param name="context">The context object for this turn.</param>
 /// <param name="instance">State information associated with the inner dialog stack of this
 /// component dialog.</param>
 /// <param name="reason">Reason why the dialog ended.</param>
 /// <param name="cancellationToken">A cancellation token that can be used by other objects
 /// or threads to receive notice of cancellation.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 /// <remarks>Override this method in a derived class to implement any additional logic that
 /// should happen at the component level, after all inner dialogs have been canceled.</remarks>
 /// <seealso cref="EndDialogAsync(ITurnContext, DialogInstance, DialogReason, CancellationToken)"/>
 protected virtual Task OnEndDialogAsync(ITurnContext context, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(Task.CompletedTask);
 }
コード例 #4
0
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
        {
            if (result is ActionScopeResult actionScopeResult)
            {
                return(await OnActionScopeResultAsync(dc, actionScopeResult, cancellationToken).ConfigureAwait(false));
            }

            return(await OnNextActionAsync(dc, result, cancellationToken).ConfigureAwait(false));
        }
コード例 #5
0
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (this.ResultProperty != null)
            {
                dc.State.SetValue(this.ResultProperty.GetValue(dc.State), result);
            }

            // By default just end the current dialog and return result to parent.
            return(await dc.EndDialogAsync(result, cancellationToken).ConfigureAwait(false));
        }
コード例 #6
0
 /// <summary>
 /// Called when a child dialog completed its turn, returning control to this dialog.
 /// </summary>
 /// <param name="dc">The dialog context for the current turn of the conversation.</param>
 /// <param name="reason">Reason why the dialog resumed.</param>
 /// <param name="result">Optional, value returned from the dialog that was called. The type
 /// of the value returned is dependent on the child dialog.</param>
 /// <param name="cancellationToken">A cancellation token that can be used by other objects
 /// or threads to receive notice of cancellation.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public override Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
 {
     LoadDialogOptions(dc.Context, dc.ActiveDialog);
     return(base.ResumeDialogAsync(dc, reason, result, cancellationToken));
 }
コード例 #7
0
            public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
            {
                dc.State.SetValue("$xyz", result);
                await dc.Context.SendActivityAsync(dc.State.GetValue <string>("$xyz"));

                return(await dc.EndDialogAsync(result));
            }
コード例 #8
0
            public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
            {
                outerDc.GetState().SetValue(this.Property, result);
                await outerDc.Context.SendActivityAsync($"Hello {result.ToString()}, nice to meet you!");

                return(await outerDc.EndDialogAsync(result));
            }
コード例 #9
0
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null,
                                                                        CancellationToken cancellationToken = new CancellationToken())
        {
            var exeProp = (string)dc.ActiveDialog.State[Property];
            var value   = GetStoredValue(dc.ActiveDialog);

            if (result is FoundChoice resultChoice)
            {
                value[exeProp] = resultChoice.Value;
            }
            else
            {
                value[exeProp] = result;
            }

            return(await ExecuteProperty(dc, cancellation : cancellationToken));
        }
コード例 #10
0
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            var prompt = result as ResetPasswordPrompt;
            var email  = outerDc.Context.Activity.From.Id;
            int?passcode;

            using (var db = new ContosoHelpdeskContext())
            {
                passcode = db.ResetPasswords.Where(r => r.EmailAddress == email).First().PassCode;
            }

            if (prompt.PassCode == passcode)
            {
                string temppwd = "TempPwd" + new Random().Next(0, 5000);
                await outerDc.PostAsync($"Your temp password is {temppwd}");
            }

            return(new DialogTurnResult(DialogTurnStatus.Complete));
        }
コード例 #11
0
        public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken))
        {
            // Forward cancel to inner dialogs
            if (reason == DialogReason.CancelCalled)
            {
                var dialogState = (DialogState)instance.State[PersistedDialogState];
                var innerDc     = new DialogContext(_dialogs, turnContext, dialogState);
                await innerDc.CancelAllDialogsAsync(cancellationToken).ConfigureAwait(false);
            }

            await OnEndDialogAsync(turnContext, instance, reason, cancellationToken).ConfigureAwait(false);
        }
コード例 #12
0
ファイル: Dialog.cs プロジェクト: wineone/botbuilder-dotnet
 public virtual Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken))
 {
     // No-op by default
     return(Task.CompletedTask);
 }
コード例 #13
0
ファイル: Dialog.cs プロジェクト: wineone/botbuilder-dotnet
 /// <summary>
 /// Method called when an instance of the dialog is being returned to from another
 /// dialog that was started by the current instance using `DialogSet.begin()`.
 /// If this method is NOT implemented then the dialog will be automatically ended with a call
 /// to `DialogSet.endDialogWithResult()`. Any result passed from the called dialog will be passed
 /// to the current dialogs parent.
 /// </summary>
 /// <param name="dc">The dialog context for the current turn of conversation.</param>
 /// <param name="reason">Reason why the dialog resumed.</param>
 /// <param name="result">(Optional) value returned from the dialog that was called. The type of the value returned is dependant on the dialog that was called.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public virtual async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
 {
     // By default just end the current dialog and return result to parent.
     return(await dc.EndDialogAsync(result, cancellationToken).ConfigureAwait(false));
 }
コード例 #14
0
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Increment step index and run step
            var state = dc.ActiveDialog.State;

            // For issue https://github.com/Microsoft/botbuilder-dotnet/issues/871
            // See the linked issue for details. This issue was happening when using the CosmosDB
            // data store for state. The stepIndex which was an object being cast to an Int64
            // after deserialization was throwing an exception for not being Int32 datatype.
            // This change ensures the correct datatype conversion has been done.
            var index = Convert.ToInt32(state[StepIndex]);

            return(await RunStepAsync(dc, index + 1, reason, result, cancellationToken).ConfigureAwait(false));
        }
コード例 #15
0
ファイル: SkillDialog.cs プロジェクト: vman/botbuilder-dotnet
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
        {
            await RepromptDialogAsync(dc.Context, dc.ActiveDialog, cancellationToken).ConfigureAwait(false);

            return(EndOfTurn);
        }
コード例 #16
0
            public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
            {
                outerDc.State.SetValue(_property, result);
                await outerDc.Context.SendActivityAsync($"Hello {result}, nice to meet you!", cancellationToken : cancellationToken);

                return(await outerDc.EndDialogAsync(result, cancellationToken));
            }
コード例 #17
0
ファイル: SkillDialog.cs プロジェクト: vman/botbuilder-dotnet
        public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default)
        {
            // Send of of conversation to the skill if the dialog has been cancelled.
            if (reason == DialogReason.CancelCalled || reason == DialogReason.ReplaceCalled)
            {
                await turnContext.TraceActivityAsync($"{GetType().Name}.EndDialogAsync()", label : $"ActivityType: {turnContext.Activity.Type}", cancellationToken : cancellationToken).ConfigureAwait(false);

                var activity = (Activity)Activity.CreateEndOfConversationActivity();

                // Apply conversation reference and common properties from incoming activity before sending.
                activity.ApplyConversationReference(turnContext.Activity.GetConversationReference(), true);
                activity.ChannelData = turnContext.Activity.ChannelData;
                activity.Properties  = turnContext.Activity.Properties;

                // connection Name is not applicable for an EndDialog, as we don't expect as OAuthCard in response.
                await SendToSkillAsync(turnContext, activity, cancellationToken).ConfigureAwait(false);
            }

            await base.EndDialogAsync(turnContext, instance, reason, cancellationToken).ConfigureAwait(false);
        }
コード例 #18
0
 public override Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default)
 {
     if (_resetOnEnd)
     {
         Reset();
     }
     return(base.EndDialogAsync(turnContext, instance, reason, cancellationToken));
 }
コード例 #19
0
 /// <summary>
 /// Called when the dialog is ending.
 /// </summary>
 /// <param name="turnContext">The context object for this turn.</param>
 /// <param name="instance">State information associated with the instance of this dialog on the dialog stack.</param>
 /// <param name="reason">Reason why the dialog ended.</param>
 /// <param name="cancellationToken">A cancellation token that can be used by other objects
 /// or threads to receive notice of cancellation.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public override Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default)
 {
     LoadDialogOptions(turnContext, instance);
     return(base.EndDialogAsync(turnContext, instance, reason, cancellationToken));
 }
コード例 #20
0
            /// <summary>
            /// Resume is called when a child dialog completes and we need to carry on processing in this class.
            /// </summary>
            /// <param name="dialogContext">A handle on the runtime.</param>
            /// <param name="reason">The reason we have control back in this dialog.</param>
            /// <param name="result">The result from the child dialog. For example this is the value from a prompt.</param>
            /// <param name="cancellationToken">The cancellation token.</param>
            /// <returns>A DialogTurnResult indicating the state of this dialog to the caller.</returns>
            public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dialogContext, DialogReason reason, object result, CancellationToken cancellationToken = default(CancellationToken))
            {
                if (dialogContext == null)
                {
                    throw new ArgumentNullException(nameof(dialogContext));
                }

                // Update the state with the result from the child prompt.
                var slotName = (string)dialogContext.ActiveDialog.State[SlotName];
                var values   = GetPersistedValues(dialogContext.ActiveDialog);

                values[slotName] = result;

                // Run prompt.
                return(await RunPromptAsync(dialogContext, cancellationToken));
            }
コード例 #21
0
            public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
            {
                if ((string)result == "d2")
                {
                    return(await dc.EndDialogAsync());
                }

                var name = dc.State.GetValue <string>("$name");
                await dc.Context.SendActivityAsync(name);

                name = dc.State.GetValue <string>("dialog.name");
                await dc.Context.SendActivityAsync(name);

                return(await dc.BeginDialogAsync("d2"));
            }
コード例 #22
0
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
        {
            string nextStep = (string)dc.ActiveDialog.State["stepID"];

            dc.ActiveDialog.State[nextStep] = dc.Context.Activity.Text;
            return(await ContinueDialogAsync(dc, cancellationToken));
        }
コード例 #23
0
 internal WaterfallStepContext(WaterfallDialog parent, DialogContext dc, object options, IDictionary <string, object> values, int index, DialogReason reason, object result = null)
     : base(dc.Dialogs, dc.Context, new DialogState(dc.Stack))
 {
     _parent     = parent;
     _nextCalled = false;
     Index       = index;
     Options     = options;
     Reason      = reason;
     Result      = result;
     Values      = values;
 }
コード例 #24
0
        public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken)
        {
            if (reason == DialogReason.CancelCalled)
            {
                // when dialog is being ended/cancelled, send an activity to skill
                // to cancel all dialogs on the skill side
                if (_skillTransport != null)
                {
                    await _skillTransport.CancelRemoteDialogsAsync(turnContext);
                }
            }

            await base.EndDialogAsync(turnContext, instance, reason, cancellationToken);
        }
コード例 #25
0
 public override Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(null);
 }
コード例 #26
0
        public override async Task DialogEndAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken))
        {
            // Notify inner dialog
            var dialogState = (DialogState)instance.State[PersistedDialogState];
            var cdc         = new DialogContext(_dialogs, turnContext, dialogState);

            await OnDialogEndAsync(cdc, reason, cancellationToken).ConfigureAwait(false);
        }
コード例 #27
0
        /// <summary>
        /// Called when the dialog is ending.
        /// </summary>
        /// <param name="turnContext">The context object for this turn.</param>
        /// <param name="instance">State information associated with the instance of this component
        /// dialog on its parent's dialog stack.</param>
        /// <param name="reason">Reason why the dialog ended.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        /// <remarks>When this method is called from the parent dialog's context, the component dialog
        /// cancels all of the dialogs on its inner dialog stack before ending.</remarks>
        /// <seealso cref="OnEndDialogAsync(ITurnContext, DialogInstance, DialogReason, CancellationToken)"/>
        /// <seealso cref="DialogContext.EndDialogAsync(object, CancellationToken)"/>
        public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken))
        {
            // Forward cancel to inner dialogs
            if (reason == DialogReason.CancelCalled)
            {
                var innerDc = this.CreateInnerDc(turnContext, instance);
                await innerDc.CancelAllDialogsAsync(cancellationToken : cancellationToken).ConfigureAwait(false);
            }

            await OnEndDialogAsync(turnContext, instance, reason, cancellationToken).ConfigureAwait(false);
        }
コード例 #28
0
 protected override Task OnEndDialogAsync(ITurnContext context, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default)
 {
     // Capture the end reason for assertions.
     EndReason = reason;
     return(base.OnEndDialogAsync(context, instance, reason, cancellationToken));
 }
コード例 #29
0
        public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            // Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs
            // on top of the stack which will result in the prompt receiving an unexpected call to
            // dialogResume() when the pushed on dialog ends.
            // To avoid the prompt prematurely ending we need to implement this method and
            // simply re-prompt the user.
            await RepromptDialogAsync(dc.Context, dc.ActiveDialog).ConfigureAwait(false);

            return(Dialog.EndOfTurn);
        }
コード例 #30
0
        /// <summary>
        /// Called when the dialog is ending.
        /// </summary>
        /// <param name="turnContext">Context for the current turn of conversation.</param>
        /// <param name="instance">The instance of the current dialog.</param>
        /// <param name="reason">he reason the dialog is ending.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        public override Task EndDialogAsync(ITurnContext turnContext, DialogInstance instance, DialogReason reason, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (reason == DialogReason.CancelCalled)
            {
                // Create step context
                var index      = Convert.ToInt32(instance.State[StepIndex]);
                var stepName   = WaterfallStepName(index);
                var instanceId = instance.State[PersistedInstanceId] as string;

                var properties = new Dictionary <string, string>()
                {
                    { "DialogId", Id },
                    { "StepName", stepName },
                    { "InstanceId", instanceId },
                };
                TelemetryClient.TrackEvent("WaterfallCancel", properties);
            }
            else if (reason == DialogReason.EndCalled)
            {
                var instanceId = instance.State[PersistedInstanceId] as string;
                var properties = new Dictionary <string, string>()
                {
                    { "DialogId", Id },
                    { "InstanceId", instanceId },
                };
                TelemetryClient.TrackEvent("WaterfallComplete", properties);
            }

            return(Task.CompletedTask);
        }