Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 未调用框架恢复对话框_C#_Botframework - Fatal编程技术网

C# 未调用框架恢复对话框

C# 未调用框架恢复对话框,c#,botframework,C#,Botframework,我在botframework V4中的组件对话框出现问题 我正在使用一个根对话框,其中包含一个WaterWallDialog和一个Setupdialog。初始对话框是设置对话框。像这样: public RootDialog(SetupDialog setupDialog) : base(nameof(RootDialog)) { AddDialog(setupDialog); AddDialog(new Te


我在botframework V4中的组件对话框出现问题

我正在使用一个根对话框,其中包含一个WaterWallDialog和一个Setupdialog。初始对话框是设置对话框。像这样:

public RootDialog(SetupDialog setupDialog)
            : base(nameof(RootDialog))
        {
            AddDialog(setupDialog);
            AddDialog(new TextPrompt(nameof(TextPrompt)));
            AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
            {
                ProcessStep
            }));
            InitialDialogId = nameof(SetupDialog);
        }
在设置对话框中,我询问一些值。如果设置对话框继续,我将检查该值,如果它符合我的要求,我将结束对话框

public override Task<DialogTurnResult> ContinueDialogAsync(DialogContext outerDc, CancellationToken cancellationToken = default)
        {
            if (!int.TryParse(outerDc.Context.Activity.Text, out var recursions))
            {
                return outerDc.PromptAsync(nameof(TextPrompt), new PromptOptions()
                {
                    Prompt = MessageFactory.Text($"{outerDc.Context.Activity.Text} konnte nicht in eine Zahl konvertiert werden.")
                });
            }

            return outerDc.EndDialogAsync(recursions);
        }
public override Task continuedialgasync(DialogContext outerDc,CancellationToken CancellationToken=default)
{
if(!int.TryParse(outerDc.Context.Activity.Text,out-var递归))
{
返回outerDc.PromptAsync(nameof(TextPrompt),newpromptoptions()
{
Prompt=MessageFactory.Text($“{outerDc.Context.Activity.Text}konnte nicht in eine Zahl konvertiert werden.”)
});
}
返回outerDc.EndDialogAsync(递归);
}
如果我像这样结束对话框,不应该在RootDialog中调用ResumeDialog吗

下面是整个对话框:

public class RootDialog : ComponentDialog
    {
        private int recursions;

        public RootDialog(SetupDialog setupDialog)
            : base(nameof(RootDialog))
        {
            AddDialog(setupDialog);
            AddDialog(new TextPrompt(nameof(TextPrompt)));
            AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
            {
                ProcessStep
            }));
            InitialDialogId = nameof(SetupDialog);
        }

        public async Task<DialogTurnResult> ProcessStep(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {

            await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions
            {
                Prompt = MessageFactory.Text("Process step in root dialog")
            });

            if(Dialogs.Find(nameof(RecursiveDialog)) == null)
            {
                AddDialog(new RecursiveDialog(new DialogSet(), recursions));
            }

            if (recursions > 0)
            {
                return await stepContext.BeginDialogAsync(nameof(RecursiveDialog));
            }

            return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions
            {
                Prompt = MessageFactory.Text("Recursion lower or eqaul 0")
            });
        }

        public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext outerDc, object options = null, CancellationToken cancellationToken = default)
        {
            var dialogContext = CreateChildContext(outerDc);
            await dialogContext.PromptAsync(nameof(TextPrompt), new PromptOptions
            {
                Prompt = MessageFactory.Text("Begin root dialog")
            });

            return await base.BeginDialogAsync(outerDc, options, cancellationToken);
        }

        public override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default)
        {
            if(innerDc.ActiveDialog != null)
            {
                return await innerDc.ContinueDialogAsync();
            }

            return await base.OnContinueDialogAsync(innerDc, cancellationToken);
        }

        public override async Task<DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
        {
            recursions = Convert.ToInt32(result);

            await outerDc.PromptAsync(nameof(TextPrompt), new PromptOptions
            {
                Prompt = MessageFactory.Text($"Resume root dialog with recursion value {recursions}")
            });

            return await outerDc.BeginDialogAsync(nameof(WaterfallDialog));
        }
    }
公共类RootDialog:ComponentDialog
{
私有int递归;
公共根对话框(设置对话框设置对话框)
:base(nameof(RootDialog))
{
AddDialog(setupDialog);
AddDialog(新建文本提示(名称)(文本提示));
AddDialog(新建WaterWallDialog)(名称(WaterWallDialog),新建WaterWallStep[]
{
过程步骤
}));
InitialDialogId=nameof(SetupDialog);
}
公共异步任务ProcessStep(WaterWallStepContext stepContext,CancellationToken CancellationToken)
{
等待stepContext.PromptAsync(nameof(TextPrompt),新PromptOptions
{
Prompt=MessageFactory.Text(“根对话框中的处理步骤”)
});
if(Dialogs.Find(nameof(RecursiveDialog))==null)
{
AddDialog(新建RecursiveDialog(新建DialogSet(),递归));
}
如果(递归>0)
{
return wait-stepContext.BeginDialogAsync(nameof(RecursiveDialog));
}
return wait stepContext.PromptAsync(nameof(TextPrompt)),new PromptOptions
{
Prompt=MessageFactory.Text(“递归下限或eqaul 0”)
});
}
公共重写异步任务BeginDialogAsync(DialogContext outerDc,对象选项=null,CancellationToken CancellationToken=default)
{
var dialogContext=CreateChildContext(outerDc);
等待dialogContext.PromptAsync(nameof(TextPrompt)),新PromptOptions
{
Prompt=MessageFactory.Text(“开始根对话框”)
});
return wait base.BeginDialogAsync(outerDc、options、cancellationToken);
}
公共覆盖异步任务OnContinueDialogAsync(DialogContext innerDc,CancellationToken CancellationToken=default)
{
如果(innerDc.ActiveDialog!=null)
{
return wait innerDc.ContinueDialogAsync();
}
返回wait base.OnContinueDialogAsync(innerDc,cancellationToken);
}
公共覆盖异步任务ResumeDialogAsync(DialogContext-outerDc,DialogReason-reason,对象结果=null,CancellationToken CancellationToken=default)
{
递归=Convert.ToInt32(结果);
等待outerDc.PromptAsync(nameof(TextPrompt)),新建PromptOptions
{
Prompt=MessageFactory.Text($“使用递归值{recursions}恢复根对话框”)
});
return wait outerDc.BeginDialogAsync(nameof(waterwalldialog));
}
}
设置对话框:

 public class SetupDialog : ComponentDialog
    {
        public SetupDialog()
            : base(nameof(SetupDialog))
        {
            AddDialog(new TextPrompt(nameof(TextPrompt)));
        }

        public override Task<DialogTurnResult> ContinueDialogAsync(DialogContext outerDc, CancellationToken cancellationToken = default)
        {
            if (!int.TryParse(outerDc.Context.Activity.Text, out var recursions))
            {
                return outerDc.PromptAsync(nameof(TextPrompt), new PromptOptions()
                {
                    Prompt = MessageFactory.Text($"{outerDc.Context.Activity.Text} konnte nicht in eine Zahl konvertiert werden.")
                });
            }

            return outerDc.EndDialogAsync(recursions);
        }

        public override Task<DialogTurnResult> OnBeginDialogAsync(DialogContext innerDc, object options, CancellationToken cancellationToken = default)
        {
            return innerDc.PromptAsync(nameof(TextPrompt), new PromptOptions()
            {
                Prompt = MessageFactory.Text("Wie viel rekursionen sollen erstellt werden?")
            });
        }
    }
公共类设置对话框:组件对话框
{
公共设置对话框()
:base(名称(设置对话框))
{
AddDialog(新建文本提示(名称)(文本提示));
}
公共覆盖任务ContinueDialogAsync(DialogContext outerDc,CancellationToken CancellationToken=default)
{
if(!int.TryParse(outerDc.Context.Activity.Text,out-var递归))
{
返回outerDc.PromptAsync(nameof(TextPrompt),newpromptoptions()
{
Prompt=MessageFactory.Text($“{outerDc.Context.Activity.Text}konnte nicht in eine Zahl konvertiert werden.”)
});
}
返回outerDc.EndDialogAsync(递归);
}
公共覆盖任务OnBeginDialogAsync(DialogContext innerDc,对象选项,CancellationToken CancellationToken=default)
{
返回innerDc.PromptAsync(nameof(TextPrompt),newpromptoptions()
{
Prompt=MessageFactory.Text(“您觉得如何?”
});
}
}

因此,我得到了要触发的ResumeDialog方法

要触发ResumeDialog方法,结束的对话框和要恢复的对话框必须位于同一个对话框堆栈上

我的场景是BotDialogContext[RootDialog]->RootDialogContext[SetupDialog],但我需要类似于BotDialogContext[RootDialog,SetupDialog]的上下文

问题之一是,您启动的每个ComponentDialog都会创建自己的DialogContext。因此,如果在对话框中开始一个对话框,它会被推到内部DialogContext的堆栈上,依此类推。但是ResumeDialog方法的描述是

当父对话框堆栈上的子对话框完成此回合时调用,将控制权返回到此对话框组件

要在父对话框堆栈上放置子对话框,必须在外部对话框上下文上调用BeginDialog方法。此上下文还需要在其对话框集中设置“子对话框”

以下是我的例子:

RootDialog.cs:

public class RootDialog : ComponentDialog
{
    private int recursions;

    public RootDialog(SetupDialog setupDialog)
        : base(nameof(RootDialog))
    {
        AddDialog(setupDialog);
        AddDialog(new TextPrompt(nameof(TextPrompt)));
        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
        {
            ProcessStep
        }));
        InitialDialogId = nameof(SetupDialog);
    }

    public async Task<DialogTurnResult> ProcessStep(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {

        await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions
        {
            Prompt = MessageFactory.Text("Process step in root dialog")
        });

        if(Dialogs.Find(nameof(RecursiveDialog)) == null)
        {
            AddDialog(new RecursiveDialog(new DialogSet(), recursions));
        }

        if (recursions > 0)
        {
            return await stepContext.BeginDialogAsync(nameof(RecursiveDialog));
        }

        return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions
        {
            Prompt = MessageFactory.Text("Recursion lower or eqaul 0")
        });
    }

    public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext outerDc, object options = null, CancellationToken cancellationToken = default)
    {
        if (true)
        {
            return await outerDc.BeginDialogAsync(nameof(SetupDialog));
        }

        var dialogContext = CreateChildContext(outerDc);
        await dialogContext.PromptAsync(nameof(TextPrompt), new PromptOptions
        {
            Prompt = MessageFactory.Text("Begin root dialog")
        });

        return await base.BeginDialogAsync(outerDc, options, cancellationToken);
    }

    protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default)
    {
        if(innerDc.ActiveDialog != null)
        {
            return await innerDc.ContinueDialogAsync();
        }
        return await base.OnContinueDialogAsync(innerDc, cancellationToken);
    }

    public override async Task<DialogTurnResult> ResumeDialogAsync(DialogContext outerDc, DialogReason reason, object result = null, CancellationToken cancellationToken = default)
    {
        recursions = Convert.ToInt32(result);

        await outerDc.PromptAsync(nameof(TextPrompt), new PromptOptions
        {
            Prompt = MessageFactory.Text($"Resume root dialog with recursion value {recursions}")
        });

        return await outerDc.BeginDialogAsync(nameof(WaterfallDialog));
    }
}
public class SetupDialog : ComponentDialog
{
    public SetupDialog()
        : base(nameof(SetupDialog))
    {
        AddDialog(new TextPrompt(nameof(TextPrompt)));
    }

    public override Task<DialogTurnResult> ContinueDialogAsync(DialogContext outerDc, CancellationToken cancellationToken = default)
    {
        if (!int.TryParse(outerDc.Context.Activity.Text, out var recursions))
        {
            return outerDc.PromptAsync(nameof(TextPrompt), new PromptOptions()
            {
                Prompt = MessageFactory.Text($"{outerDc.Context.Activity.Text} konnte nicht in eine Zahl konvertiert werden.")
            });
        }

        return outerDc.EndDialogAsync(recursions);
    }

    public override Task<DialogTurnResult> BeginDialogAsync(DialogContext outerDc, object options = null, CancellationToken cancellationToken = default)
    {
        return base.BeginDialogAsync(outerDc, options, cancellationToken);
    }

    protected override Task<DialogTurnResult> OnBeginDialogAsync(DialogContext innerDc, object options, CancellationToken cancellationToken = default)
    {
        return innerDc.PromptAsync(nameof(TextPrompt), new PromptOptions()
        {
            Prompt = MessageFactory.Text("Wie viel rekursionen sollen erstellt werden?")
        });
    }
}
公共类RootDialog:ComponentDialog
{
私有int递归;
公共根对话框(Setu)
public class DialogBot<T> : ActivityHandler
    where T : Dialog
{
    protected readonly DialogSet Dialogs;
    protected readonly BotState ConversationState;
    protected readonly BotState UserState;
    protected readonly ILogger Logger;

    public DialogBot(ConversationState conversationState, UserState userState, IEnumerable<Dialog> dialogs, ILogger<DialogBot<T>> logger)
    {
        ConversationState = conversationState;
        UserState = userState;
        Logger = logger;

        Dialogs = new DialogSet(conversationState.CreateProperty<DialogState>(nameof(DialogState)));
        foreach(var dialog in dialogs)
        {
            Dialogs.Add(dialog);
        }
    }

    public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
    {
        await base.OnTurnAsync(turnContext, cancellationToken);

        // Save any state changes that might have occured during the turn.
        await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
        await UserState.SaveChangesAsync(turnContext, false, cancellationToken);
    }

    protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
    {
        Logger.LogInformation("Running dialog with Message Activity.");

        var dc = await Dialogs.CreateContextAsync(turnContext, cancellationToken).ConfigureAwait(false);

        if (dc.ActiveDialog != null)
        {
            await dc.ContinueDialogAsync();
        }
        else
        {
            // Run the Dialog with the new message Activity.
            await dc.BeginDialogAsync(typeof(T).Name, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
        }
    }
}