C# Microsoft Bot Framework转发到对话框无法正常工作

C# Microsoft Bot Framework转发到对话框无法正常工作,c#,botframework,C#,Botframework,我有两个对话。在第一个示例中,如果结果符合我的条件,我将转发到第二个示例,代码如下所示: /// <summary> /// Intent for choosing a category /// </summary> /// <param name="context">The current context</param> /// <param name="result">The Luis result</param> //

我有两个对话。在第一个示例中,如果结果符合我的条件,我将转发到第二个示例,代码如下所示:

/// <summary>
/// Intent for choosing a category
/// </summary>
/// <param name="context">The current context</param>
/// <param name="result">The Luis result</param>
/// <returns></returns>
[LuisIntent("Choose category")]
public async Task ChooseCategory(IDialogContext context, LuisResult result)
{

    // Get our category
    var category = TryFindCategory(result);
    var response = "The category you have chosen is not in the system just yet.";

    switch (category)
    {
        case "camera":

            // If our category is a camera, forward to our QuestionDialog
            await context.Forward(new QuestionDialog(), ResumeAfter, new Activity { Text = result.Query }, CancellationToken.None);
            break;
        default:

            // If we have an unknown category, update the response message
            if (!string.IsNullOrEmpty(category)) response = $"Sorry, PiiiCK does not deal with { category.Pluralise() } just yet.";

            // Post our response back to the user
            await context.PostAsync(response);

            // Execute the message recieved delegate
            context.Wait(MessageReceived);
            break;
    }
}

/// <summary>
/// Delgate function for resuming after a response have been recieved from LUIS
/// </summary>
/// <param name="context">The current context</param>
/// <param name="result">The Luis result</param>
/// <returns></returns>
private async Task ResumeAfter(IDialogContext context, IAwaitable<object> result)
{
    context.Wait(MessageReceived);
}
[Serializable]
public class QuestionDialog : IDialog<object>
{

    // Private properties
    private readonly QuestionGroupService _questionGroupService;
    private IList<QuestionGroup> _questionGroups;

    /// <summary>
    /// Gets a list of QuestionGroups
    /// </summary>
    /// <returns>A list of QuestionGroups</returns>
    public async Task<IList<QuestionGroup>> QuestionGroups() => _questionGroups ?? (_questionGroups = await _questionGroupService.ListAllAsync());

    /// <summary>
    /// Default constructor
    /// </summary>
    public QuestionDialog()
    {
        _questionGroupService = new QuestionGroupService(new UnitOfWork<DatabaseContext>());
    }

    /// <summary>
    /// Start our response
    /// </summary>
    /// <param name="context">The current context</param>
    /// <returns></returns>
    public async Task StartAsync(IDialogContext context) => context.Wait(ActivityRecievedAsync);

    /// <summary>
    /// When our message is recieved we execute this delegate
    /// </summary>
    /// <param name="context">The current context</param>
    /// <param name="result">The result object</param>
    /// <returns></returns>
    private async Task ActivityRecievedAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("This is my first question?");
        context.Wait(GroupOneAnswerAsync);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="context">The current context</param>
    /// <param name="result">The result object</param>
    /// <returns></returns>
    private async Task GroupOneAnswerAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("This is my second question?");
        context.Wait(GroupTwoAnswerAsync);
    }

    private async Task GroupTwoAnswerAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("This is my third question?");
        context.Wait(GroupThreeAnswerAsync);
    }

    private async Task GroupThreeAnswerAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("This is my third question?");
        context.Wait(GetResultsAsync);
    }

    private async Task GetResultsAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("These are my results");
        context.Wait(ActivityRecievedAsync);
    }
}
//
///选择类别的意图
/// 
///当前环境
///路易斯的结果
/// 
[LUISINT(“选择类别”)]
公共异步任务ChooseCategory(IDialogContext上下文,LuisResult结果)
{
//获取我们的类别
var类别=TryFindCategory(结果);
var response=“您选择的类别还不在系统中。”;
开关(类别)
{
“照相机”案例:
//如果我们的类别是照相机,请转到问题对话框
wait context.Forward(new QuestionDialog(),ResumeAfter,新活动{Text=result.Query},CancellationToken.None);
打破
违约:
//如果我们有未知类别,请更新响应消息
如果(!string.IsNullOrEmpty(category))response=$“对不起,PiiiCK还没有处理{category.multilate()}。”;
//将我们的回复发回给用户
等待上下文。PostAsync(响应);
//执行消息received delegate
Wait(MessageReceived);
打破
}
}
/// 
///Delgate功能,用于在收到LUIS的响应后恢复
/// 
///当前环境
///路易斯的结果
/// 
专用异步任务ResumeAfter(IDialogContext上下文,IAwaitable结果)
{
Wait(MessageReceived);
}
我的问题对话框设置如下:

/// <summary>
/// Intent for choosing a category
/// </summary>
/// <param name="context">The current context</param>
/// <param name="result">The Luis result</param>
/// <returns></returns>
[LuisIntent("Choose category")]
public async Task ChooseCategory(IDialogContext context, LuisResult result)
{

    // Get our category
    var category = TryFindCategory(result);
    var response = "The category you have chosen is not in the system just yet.";

    switch (category)
    {
        case "camera":

            // If our category is a camera, forward to our QuestionDialog
            await context.Forward(new QuestionDialog(), ResumeAfter, new Activity { Text = result.Query }, CancellationToken.None);
            break;
        default:

            // If we have an unknown category, update the response message
            if (!string.IsNullOrEmpty(category)) response = $"Sorry, PiiiCK does not deal with { category.Pluralise() } just yet.";

            // Post our response back to the user
            await context.PostAsync(response);

            // Execute the message recieved delegate
            context.Wait(MessageReceived);
            break;
    }
}

/// <summary>
/// Delgate function for resuming after a response have been recieved from LUIS
/// </summary>
/// <param name="context">The current context</param>
/// <param name="result">The Luis result</param>
/// <returns></returns>
private async Task ResumeAfter(IDialogContext context, IAwaitable<object> result)
{
    context.Wait(MessageReceived);
}
[Serializable]
public class QuestionDialog : IDialog<object>
{

    // Private properties
    private readonly QuestionGroupService _questionGroupService;
    private IList<QuestionGroup> _questionGroups;

    /// <summary>
    /// Gets a list of QuestionGroups
    /// </summary>
    /// <returns>A list of QuestionGroups</returns>
    public async Task<IList<QuestionGroup>> QuestionGroups() => _questionGroups ?? (_questionGroups = await _questionGroupService.ListAllAsync());

    /// <summary>
    /// Default constructor
    /// </summary>
    public QuestionDialog()
    {
        _questionGroupService = new QuestionGroupService(new UnitOfWork<DatabaseContext>());
    }

    /// <summary>
    /// Start our response
    /// </summary>
    /// <param name="context">The current context</param>
    /// <returns></returns>
    public async Task StartAsync(IDialogContext context) => context.Wait(ActivityRecievedAsync);

    /// <summary>
    /// When our message is recieved we execute this delegate
    /// </summary>
    /// <param name="context">The current context</param>
    /// <param name="result">The result object</param>
    /// <returns></returns>
    private async Task ActivityRecievedAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("This is my first question?");
        context.Wait(GroupOneAnswerAsync);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="context">The current context</param>
    /// <param name="result">The result object</param>
    /// <returns></returns>
    private async Task GroupOneAnswerAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("This is my second question?");
        context.Wait(GroupTwoAnswerAsync);
    }

    private async Task GroupTwoAnswerAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("This is my third question?");
        context.Wait(GroupThreeAnswerAsync);
    }

    private async Task GroupThreeAnswerAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("This is my third question?");
        context.Wait(GetResultsAsync);
    }

    private async Task GetResultsAsync(IDialogContext context, IAwaitable<object> result)
    {

        // Get our activity
        var activity = await result as Activity;

        // If it contains test
        await context.PostAsync("These are my results");
        context.Wait(ActivityRecievedAsync);
    }
}
[可序列化]
公共类问题对话框:IDialog
{
//私有财产
私有只读QuestionGroupService\u QuestionGroupService;
私人IList组;
/// 
///获取问题组的列表
/// 
///问题组列表
公共异步任务QuestionGroups()=>\u QuestionGroups???(\u QuestionGroups=wait\u questionGroupService.listallsync());
/// 
///默认构造函数
/// 
公共问题对话()
{
_questionGroupService=new questionGroupService(new UnitOfWork());
}
/// 
///开始我们的反应
/// 
///当前环境
/// 
公共异步任务StartAsync(IDialogContext上下文)=>context.Wait(ActivityRecievedAsync);
/// 
///收到消息后,我们执行此委托
/// 
///当前环境
///结果对象
/// 
专用异步任务ActivityRecievedAsync(IDialogContext上下文,IAwaitable结果)
{
//得到我们的活动
var活动=等待作为活动的结果;
//如果它包含测试
wait context.PostAsync(“这是我的第一个问题?”);
Wait(GroupOneAnswerAsync);
}
/// 
/// 
/// 
///当前环境
///结果对象
/// 
专用异步任务GroupOneAnswerAsync(IDialogContext上下文,IAwaitable结果)
{
//得到我们的活动
var活动=等待作为活动的结果;
//如果它包含测试
wait context.PostAsync(“这是我的第二个问题?”);
Wait(GroupTwoAnswerAsync);
}
专用异步任务GroupTwoAnswerAsync(IDialogContext上下文,IAwaitable结果)
{
//得到我们的活动
var活动=等待作为活动的结果;
//如果它包含测试
wait context.PostAsync(“这是我的第三个问题?”);
Wait(GroupThreeAnswerAsync);
}
专用异步任务组ThreeAnswerAsync(IDialogContext上下文,IAwaitable结果)
{
//得到我们的活动
var活动=等待作为活动的结果;
//如果它包含测试
wait context.PostAsync(“这是我的第三个问题?”);
Wait(GetResultsAsync);
}
专用异步任务GetResultsAsync(IDialogContext上下文,IAwaitable结果)
{
//得到我们的活动
var活动=等待作为活动的结果;
//如果它包含测试
wait context.PostAsync(“这些是我的结果”);
Wait(ActivityRecievedAsync);
}
}
当我对此进行测试时,当第一个对话框转发到第二个对话框时,它会调用StartAsync方法,但从不调用ActivityRecievedAsync
有人知道原因吗?

根据您在聊天中的讨论,请确保您正在运行最新版本的BotBuilder,因为我们可能会遇到以前版本中的已知问题

另外(与问题无关,但作为一种良好做法),您可能希望更改的签名

private async Task ActivityRecievedAsync(IDialogContext context, IAwaitable<object> result)
等待活动参数并在context.Forward中使用它

一些有趣的资源:

  • 一个很好的样品

我现在没有笔记本电脑可以调试,但您可以尝试以下方法:更改ChooseCategory intent方法的签名,将第二个参数改为3个参数,而不是2个:I可等待活动。然后尝试将该活动而不是您正在创建的活动发送到对话框不幸的是,这也不起作用:(我指的是等待该活动,但您发现是的,我尝试了,但我遇到了相同的问题:(我希望有一些关于context.Forward的文档…哦,等等,我知道发生了什么!将ActivityRecievedAsync的签名更改为IAwaitable而不是IAwaitable。这不重要对话框是IDialog,“object”代表其他对话框的结果(context.Done)不是因为输入。是的,这很好。错误是因为输出了一个小版本,但我同意你的最佳实践,所以我确保它们都是这样。对于LUIS签名,这是我需要的实体,而不是原始活动,这就是为什么我在最初的帖子中没有使用它的原因,但这是需要注意的,因为我知道我将来不需要它