C# 如何在Bot框架中从RootDialog转发到LuisDialog

C# 如何在Bot框架中从RootDialog转发到LuisDialog,c#,bots,botframework,azure-language-understanding,C#,Bots,Botframework,Azure Language Understanding,我正在为FAQ创建一个机器人。当bot启动对话时,发送一个带有两个选项的提示对话框:英语、法语 当用户选择英语按钮时,我想将对话框转发到英语界面,当用户选择法语按钮时,我想将对话框转发到法语界面 这是我的密码: Rootdialog.cs public class RootDialog : IDialog<object> { private const string EnglishMenu = "English"; private const string Frenc

我正在为FAQ创建一个机器人。当bot启动对话时,发送一个带有两个选项的提示对话框:英语、法语

当用户选择英语按钮时,我想将对话框转发到英语界面,当用户选择法语按钮时,我想将对话框转发到法语界面

这是我的密码:

Rootdialog.cs

public class RootDialog : IDialog<object>
{
    private const string EnglishMenu = "English";
    private const string FrenchMenu = "French";
    private const string QAMenu = "Q&A";

    private List<string> mainMenuList = new List<string>() { EnglishMenu, FrenchMenu, QAMenu };
    private string location;

    public async Task StartAsync(IDialogContext context)
    {
        await context.PostAsync("Welcome to Root Dialog");
        context.Wait(MessageReceiveAsync);
    }

    private async Task MessageReceiveAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
        var reply = await result;
        if (reply.Text.ToLower().Contains("help"))
        {
            await context.PostAsync("You can implement help menu here");
        }
        else
        {
            await ShowMainmenu(context);
        }
    }

    private async Task ShowMainmenu(IDialogContext context)
    {
        //Show menues
        PromptDialog.Choice(context, this.CallDialog, this.mainMenuList, "What do you want to do?");
    }

    private async Task CallDialog(IDialogContext context, IAwaitable<string> result)
    {
        //This method is resume after user choise menu
       // this.luisResult = result;
       // var message = await result;
        var selectedMenu = await result;
        var message = await result;
        switch (selectedMenu)
        {
            case EnglishMenu:
                //Call child dialog without data
               //  context.Call(new EnglishLuis(),ResumeAfterDialog);
                //  context.Call(new EnglishLuis(), ResumeAfterDialog);

               await Conversation.SendAsync(context.MakeMessage(), () => new EnglishLuis());
                break;
            case FrenchMenu:
                //Call child dialog with data
                context.Call(new HotelDialog(location), ResumeAfterDialog);
                break;
            case QAMenu:
                context.Call(new LuisCallDialog(),ResumeAfterDialog);
                break;
        }

    }



    private async Task ResumeAfterDialog(IDialogContext context, IAwaitable<object> result)
    {
        //Resume this method after child Dialog is done.
        var test = await result;
        if (test != null)
        {
            location = test.ToString();
        }
        else
        {
            location = null;
        }
        await this.ShowMainmenu(context);
    }
}
public类RootDialog:IDialog
{
private const string EnglishMenu=“英语”;
private const string frenchmen=“French”;
private const string qamunu=“Q&A”;
private List mainMenuList=新列表(){EnglishMenu,FrenchMenu,QAMenu};
私有字符串位置;
公共异步任务StartAsync(IDialogContext上下文)
{
wait context.PostAsync(“欢迎使用根目录对话框”);
Wait(MessageReceiveAsync);
}
专用异步任务消息ReceiveAsync(IDialogContext上下文,IAwaitable结果)
{
var reply=等待结果;
if(reply.Text.ToLower()包含(“帮助”))
{
wait context.PostAsync(“您可以在此处实现帮助菜单”);
}
其他的
{
等待ShowMain菜单(上下文);
}
}
专用异步任务ShowMain菜单(IDialogContext上下文)
{
//展示菜单
Choice(context,this.CallDialog,this.mainMenuList,“您想做什么?”);
}
专用异步任务调用对话框(IDialogContext上下文,IAwaitable结果)
{
//此方法在用户选择菜单后恢复
//this.luisResult=结果;
//var消息=等待结果;
var selectedMenu=等待结果;
var消息=等待结果;
开关(已选择菜单)
{
英国人:
//无数据调用子对话框
//调用(new EnglishLuis(),ResumeAfterDialog);
//调用(new EnglishLuis(),ResumeAfterDialog);
wait Conversation.SendAsync(context.MakeMessage(),()=>newenglishluis());
打破
案例法语菜单:
//使用数据调用子对话框
调用(新建HotelDialog(位置),ResumeAfterDialog);
打破
案例菜单:
调用(新的LuiscalDialog(),ResumeAfterDialog);
打破
}
}
专用异步任务ResumeAfterDialog(IDialogContext上下文,IAwaitable结果)
{
//完成子对话框后恢复此方法。
var测试=等待结果;
如果(测试!=null)
{
位置=test.ToString();
}
其他的
{
位置=空;
}
等待此消息。ShowMain菜单(上下文);
}
}
}

EnglishLuis.cs:

 public class EnglishLuis : LuisDialog<object>
{
    private string location;



    //   string message = $"welcome to english dialog";

    public async Task None(IDialogContext context, LuisResult result)
    {
        string message = $"Sorry, I did not understand '{result.Query}'. Please try again";

        await context.PostAsync(message);

        context.Wait(this.MessageReceived);
        context.Done(true);
    }


    [LuisIntent("gretting")]
    [LuisIntent("intentfr")]
    public async Task Greeting(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
    {


        await context.PostAsync("Welcome :) ");


        context.Wait(MessageReceived);
        context.Done(true);
    }



    [LuisIntent("test")]
    public async Task test(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
    {
        await context.PostAsync("Do you want to test our bot ? We suggest to type : hi or who are you, help etc..");
        // context.Done(true);
        context.Wait(MessageReceived);
        context.Done(true);
    }
public class EnglishLuis:LuisDialog
{
私有字符串位置;
//字符串消息=$“欢迎使用英语对话”;
公共异步任务无(IDialogContext上下文,LuisResult结果)
{
字符串消息=$“对不起,我不理解“{result.Query}”。请重试”;
等待上下文。PostAsync(消息);
context.Wait(this.MessageReceived);
上下文。完成(true);
}
[LuisIntent(“greting”)]
[LUISINT(“意向”)]
公共异步任务问候语(IDialogContext上下文、IAwaitable活动、LuisResult结果)
{
等待上下文。PostAsync(“欢迎:)”;
Wait(MessageReceived);
上下文。完成(true);
}
[LUISINT(“测试”)]
公共异步任务测试(IDialogContext上下文、IAwaitable活动、LuisResult结果)
{
wait context.PostAsync(“您想测试我们的机器人吗?我们建议键入:hi或who you,help等”);
//上下文。完成(true);
Wait(MessageReceived);
上下文。完成(true);
}
我的问题是,当我选择英语(甚至法语)时,我遇到了一个错误:向您的bot发送此消息时出错:HTTP状态代码InternalServerError

你能帮我如何启动luis dialog吗? 另外,如果我直接从MessagesController.cs开始,效果会很好……但我的目的是让人们在两种语言之间进行选择

我尝试使用:wait context.Forward(new EnglishLuis(),ResumeAfterDialog,message,CancellationToken.None)调用luis,但没有结果

新文件RootDialog.cs(已更新):

使用系统;
使用System.Collections.Generic;
使用System.Threading.Tasks;
使用Microsoft.Bot.Builder.Dialogs;
使用Microsoft.Bot.Connector;
使用系统线程;
名称空间TeamsBot.Dialogs
{
[可序列化]
公共类RootDialog:IDialog
{
private const string EnglishMenu=“英语”;
private const string frenchmen=“French”;
private const string qamunu=“Q&A”;
private List mainMenuList=新列表(){EnglishMenu,
法语菜单,QAMenu};
私有字符串位置;
私有字符串原始消息;
公共异步任务StartAsync(IDialogContext上下文)
{
wait context.PostAsync(“欢迎使用根目录对话框”);
Wait(MessageReceiveAsync);
}
专用异步任务消息ReceiveAsync(IDialogContext上下文,
(可等待的结果)
{
var reply=等待结果;
this.originalMessage=reply.Text;
if(reply.Text.ToLower()包含(“帮助”))
{
wait context.PostAsync(“您可以在此处实现帮助菜单”);
}
其他的
{
等待ShowMain菜单(上下文);
}
}
专用异步任务ShowMain菜单(IDialogContext上下文)
{
//展示菜单
PromptDialog.Choice(上下文、this.CallDialog、this.mainMenuList、,
“你想做什么?”);
}
专用异步任务调用对话框(IDialogContext上下文,IAwaitable
结果)
{
var selectedMenu=等待结果;
开关(已选择菜单)
{
英国人:
//无数据调用子对话框
var newMessage=context.MakeMessa
   using System;
   using System.Collections.Generic;
   using System.Threading.Tasks;
    using Microsoft.Bot.Builder.Dialogs;
   using Microsoft.Bot.Connector;
    using System.Threading;

   namespace TeamsBot.Dialogs
    {
[Serializable]
public class RootDialog : IDialog<object>
{
    private const string EnglishMenu = "English";
    private const string FrenchMenu = "French";
    private const string QAMenu = "Q&A";

    private List<string> mainMenuList = new List<string>() { EnglishMenu, 
        FrenchMenu, QAMenu };
    private string location;

    private string originalMessage;

    public async Task StartAsync(IDialogContext context)
    {
        await context.PostAsync("Welcome to Root Dialog");
        context.Wait(MessageReceiveAsync);
    }

    private async Task MessageReceiveAsync(IDialogContext context, 
     IAwaitable<IMessageActivity> result)
    {
        var reply = await result;

        this.originalMessage = reply.Text;




        if (reply.Text.ToLower().Contains("help"))
        {
            await context.PostAsync("You can implement help menu here");
        }
        else
        {
            await ShowMainmenu(context);
        }
    }

    private async Task ShowMainmenu(IDialogContext context)
    {
        //Show menues
        PromptDialog.Choice(context, this.CallDialog, this.mainMenuList, 
   "What do you want to do?");
    }

    private async Task CallDialog(IDialogContext context, IAwaitable<string> 
    result)
    {

        var selectedMenu = await result;
        switch (selectedMenu)
        {
            case EnglishMenu:
                //Call child dialog without data
                var newMessage = context.MakeMessage();
                newMessage.Text = reply.Text; 
                 await context.Forward(new EnglishLuis(), ResumeAfterDialog, newMessage, CancellationToken.None);
                break;
            case FrenchMenu:
                //Call child dialog with data
                //   context.Call(new HotelDialog(location), ResumeAfterDialog);

                var frenchLuis = new FrenchLuis();
                var messageToForward = await result;
             //   await context.Forward(new FrenchLuis(), ResumeAfterDialog, messageToForward, CancellationToken.None);
                break;
            case QAMenu:
                context.Call(new LuisCallDialog(),ResumeAfterDialog);
                break;
        }

    }



    private async Task ResumeAfterDialog(IDialogContext context, IAwaitable<object> result)
    {
        //Resume this method after child Dialog is done.
        var test = await result;
        if (test != null)
        {
            location = test.ToString();
        }
        else
        {
            location = null;
        }
        await this.ShowMainmenu(context);
    }
}
context.Wait(this.MessageReceived);
context.Done(true);
var newMessage = context.MakeMessage();
newMessage.Text = this.originalMessageText //the variable that contains the text of the original message that you will have to save at MessageReceiveAsync
await context.Forward(new EnglishLuis(), ResumeAfterDialog, newMessage, CancellationToken.None);


MessageReceivedAsync in RootDialog should looks like:

 private async Task MessageReceiveAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
        var reply = await result;
        if (reply.Text.ToLower().Contains("help"))
        {
            await context.PostAsync("You can implement help menu here");
        }
        else
        {
            this.originalMessage = reply.Text;
            await ShowMainmenu(context);
        }
    }
private async Task CallDialog(IDialogContext context, IAwaitable<string> result)
{
    //These two variables will be exactly the same, you only need one     
    //var selectedMenu = await result;
    var message = await result;
    switch (selectedMenu)
    {
        case EnglishMenu:
            // Forward the context to the new LuisDialog to bring it to the top of the stack.  
            // This will also send your message to it so it gets processed there.
            await context.Forward<object>(new EnglishLuis(), ResumeAfterDialog, message , CancellationToken.None);
            break;
        case FrenchMenu:
             await context.Forward<object>(new HotelDialog(location), ResumeAfterDialog, message , CancellationToken.None);
            break;
        case QAMenu:
             await context.Forward<object>(new LuisCallDialog(), ResumeAfterDialog, message , CancellationToken.None);
            context.Call(new LuisCallDialog(),ResumeAfterDialog);
            break;
    }

}
context.Wait(this.MessageReceived);
context.Done(true);
public EnglishLuis(ConstructorParameters parameters) 
    : base(new LuisService(new LuisModelAttribute(
        "<AppId>",
        "<SubscriptionKey>",
        domain: "westeurope.api.cognitive.microsoft.com")))
    {
        // Constructor Stuff...
    }