C# 如何在bot framework v4中从ActivityHandler.onMessageActivitySync启动瀑布对话框

C# 如何在bot framework v4中从ActivityHandler.onMessageActivitySync启动瀑布对话框,c#,botframework,chatbot,azure-language-understanding,C#,Botframework,Chatbot,Azure Language Understanding,我正在尝试编写一个简单的bot,当用户输入某个内容时,它将启动我的瀑布对话框。用例非常简单,但似乎不起作用,怎么了 主bot是这样设置的,我尝试在OnMessageActivityAsync函数中调用我的对话框: namespace EmptyBot1.Dialogs { public class MainChatbot : ActivityHandler { private readonly IOptions<Models.Configurations&g

我正在尝试编写一个简单的bot,当用户输入某个内容时,它将启动我的瀑布对话框。用例非常简单,但似乎不起作用,怎么了

主bot是这样设置的,我尝试在OnMessageActivityAsync函数中调用我的对话框:

namespace EmptyBot1.Dialogs
{
    public class MainChatbot : ActivityHandler
    {
        private readonly IOptions<Models.Configurations> _mySettings;
        protected readonly IRecognizer _recognizer;
        protected readonly BotState _conversationState;

        public MainChatbot(ConversationState conversationState, IOptions<Models.Configurations> mySettings, ChatbotRecognizer recognizer)
        {
            _mySettings = mySettings ?? throw new ArgumentNullException(nameof(mySettings));
            _recognizer = recognizer;
            _conversationState = conversationState;
        }

        protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            string LuisAppId = _mySettings.Value.LuisAppId;
            string LuisAPIKey = _mySettings.Value.LuisAPIKey;
            string LuisAPIHostName = _mySettings.Value.LuisAPIHostName;
            await turnContext.SendActivityAsync(MessageFactory.Text($"You Said: {turnContext.Activity.Text}"), cancellationToken);


            var luisResult = await _recognizer.RecognizeAsync<Models.ChatbotIntent>(turnContext, cancellationToken);
            Models.ChatbotIntent.Intent TopIntent = luisResult.TopIntent().intent;
            await turnContext.SendActivityAsync(MessageFactory.Text($"Your Intention Is: {TopIntent.ToString()}"), cancellationToken);

            switch (TopIntent)
            {
                case Models.ChatbotIntent.Intent.RunBot:
                    var RunBotOptions = new Models.RunBotOptions();
                    Dialog d = new MyCustomDialog();
                    // Trying to start my dialog here.
                    await d.RunAsync(turnContext, _conversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
                    break;
                default:
                    break;
            }
            return;
        }


    }
}
一切都注入startup.cs

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        // Add functionality to inject IOptions<T>
        services.AddOptions();

        // Add our Config object so it can be injected
        services.Configure<Models.Configurations>(Configuration);

        // Create the Bot Framework Adapter with error handling enabled.
        services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

        // Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
        services.AddTransient<IBot, Dialogs.MainChatbot>();

        // Create the Conversation state. (Used by the Dialog system itself.)
        var storage = new MemoryStorage();
        var conversationState = new ConversationState(storage);
        services.AddSingleton(conversationState);



        // Register LUIS recognizer
        services.AddSingleton<ChatbotRecognizer>();

        services.AddSingleton<Dialogs.MyCustomDialog>();
    }
//此方法由运行时调用。使用此方法向容器中添加服务。
public void配置服务(IServiceCollection服务)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//添加功能以注入IOptions
services.AddOptions();
//添加我们的配置对象,以便可以注入它
服务。配置(配置);
//创建启用错误处理的Bot框架适配器。
services.AddSingleton();
//将bot创建为瞬态。在这种情况下,ASP控制器需要一个IBot。
services.AddTransient();
//创建对话状态。(由对话系统本身使用。)
var storage=newmemoryStorage();
var会话状态=新会话状态(存储);
服务。AddSingleton(会话状态);
//注册路易斯识别器
services.AddSingleton();
services.AddSingleton();
}
但当我运行它时,我得到500个错误,我做错了什么

编辑:为了澄清,我的目标是能够直接从
ActivityHandler.OnMessageActivityAsync
启动硬编码瀑布对话框

来自在线的通用解决方案和来自微软的示例项目都说将对话框作为T类型传递给我的机器人


但是,我已经知道要启动哪个对话框,因此需要将其作为类型传递,我可以直接在bot中硬编码它,如何启动它?

从我看到的情况来看,在启动时添加bot时,您没有添加bot本身。你有

// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, Dialogs.MainChatbot>();
将其更改为:

public class MainChatbot<T> : ActivityHandler
    where T : Dialog
公共类MainChatbot:ActivityHandler
其中T:Dialog

你有你的主“机器人”在那里,但你不会调用一个对话框,直到它得到路易斯的意图。但在对话框启动之前,不能调用路易斯意图。用对话框初始化你的机器人,这样你的机器人就知道从哪里开始了

结果是我的代码似乎工作正常,不知道昨天为什么不工作。我会把它留给未来的人来检查答案。您可以完全按照问题中的内容使用它。

为什么我不能硬编码启动我的CustomDialog?为什么它需要作为类型T传递?既然我有LUIS的意图,我可以准确地告诉它该启动哪个对话框,难道我不能告诉它该启动哪个对话框吗?
// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, MainChatbot<MyCustomDialog>>();
public class MainChatbot : ActivityHandler
public class MainChatbot<T> : ActivityHandler
    where T : Dialog