代码之家  ›  专栏  ›  技术社区  ›  Pedro Martins de Souza Regeesh Chandran

Azure Bot Framework仿真程序错误-系统。ArgumentNullException:值不能为null

  •  2
  • Pedro Martins de Souza Regeesh Chandran  · 技术社区  · 8 年前

    我需要一些帮助。我是Azure的Bot框架开发新手,几周前使用QnA KB创建了我的第一个聊天机器人。无论如何,我成功地在Azure的门户中创建了bot,它工作得很好。但我需要在Bot Framework Emulator(使用V4)中进行一些修改和测试,为此,下载并在本地运行我的Bot。

    我下载了我的机器人。按照Azure的指示压缩文件,并使用Visual Studio 2017作为我的IDE对其进行初始化。但是,当我按下“调试”按钮时,程序会尝试连接到 本地主机:3984

    using Autofac;
    using System.Web.Http;
    using System.Configuration;
    using System.Reflection;
    using Microsoft.Bot.Builder.Azure;
    using Microsoft.Bot.Builder.Dialogs;
    using Microsoft.Bot.Builder.Dialogs.Internals;
    using Microsoft.Bot.Connector;
    
    namespace SimpleEchoBot
    {
        public class WebApiApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                // Bot Storage: This is a great spot to register the private state storage for your bot. 
                // We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
                // For samples and documentation, see: https://github.com/Microsoft/BotBuilder-Azure
    
                Conversation.UpdateContainer(
                    builder =>
                    {
                        builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));
    
                        // Using Azure Table Storage
    
                        var store = new TableBotDataStore(ConfigurationManager.AppSettings["AzureWebJobsStorage"]); // requires Microsoft.BotBuilder.Azure Nuget package 
    
                        // To use CosmosDb or InMemory storage instead of the default table storage, uncomment the corresponding line below
                        // var store = new DocumentDbBotDataStore("cosmos db uri", "cosmos db key"); // requires Microsoft.BotBuilder.Azure Nuget package 
                        // var store = new InMemoryDataStore(); // volatile in-memory store
    
                        builder.Register(c => store)
                            .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
                            .AsSelf()
                            .SingleInstance();
    
                    });
                GlobalConfiguration.Configure(WebApiConfig.Register);
            }
        }
    }
    

    但是,在几秒钟内,以下代码行返回错误 系统ArgumentNullException:'值不能为null。 Arg\u ParamName\u Name' :

    var store = new TableBotDataStore(ConfigurationManager.AppSettings["AzureWebJobsStorage"]); // requires Microsoft.BotBuilder.Azure Nuget package 
    

    因此,我无法在bot Framework Emulator中测试我的bot。由于我对C#非常陌生,有谁能帮我解决这个问题吗?

    编辑 :这是我的网站。配置部分代码,仅删除敏感数据:

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      http://go.microsoft.com/fwlink/?LinkId=301879
      -->
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
      <appSettings>
        <!-- update these with your Microsoft App Id and your Microsoft App Password-->
        <!--<add key="BotId" value="" />-->
        <add key="MicrosoftAppId" value="" />
        <add key="MicrosoftAppPassword" value="" />
        <add key="QnaSubscriptionKey" value="" />
        <add key="QnaKnowledgebaseId" value="" />
        <add key="AzureWebJobsStorage" value="" />
    
      </appSettings>
      <!--
        For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
    
        The following attributes can be set on the <httpRuntime> tag.
          <system.Web>
            <httpRuntime targetFramework="4.6" />
          </system.Web>
      -->
      <system.web>
        <customErrors mode="Off" />
        <compilation debug="true" targetFramework="4.6" />
        <httpRuntime targetFramework="4.6" />
      </system.web>
      <system.webServer>
        <defaultDocument>
          <files>
            <clear />
            <add value="default.htm" />
          </files>
        </defaultDocument>
        <handlers>
          <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
          <remove name="OPTIONSVerbHandler" />
          <remove name="TRACEVerbHandler" />
          <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
        </handlers>
      </system.webServer>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-5.1.4.0" newVersion="5.1.4.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.IdentityModel.Protocol.Extensions" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-1.0.40306.1554" newVersion="1.0.40306.1554" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Bot.Connector" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-3.15.2.2" newVersion="3.15.2.2" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Bot.Builder" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-3.15.2.2" newVersion="3.15.2.2" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Azure.Documents.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-1.11.0.0" newVersion="1.11.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Bot.Builder.History" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-3.12.2.4" newVersion="3.12.2.4" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Bot.Builder.Autofac" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-3.15.2.2" newVersion="3.15.2.2" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-5.7.0.0" newVersion="5.7.0.0" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
      <system.codedom>
        <compilers>
          <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
          <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
        </compilers>
      </system.codedom>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="mssqllocaldb" />
          </parameters>
        </defaultConnectionFactory>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
      </entityFramework>
    </configuration>
    

    编辑2 :目前该问题的一些屏幕截图: enter image description here

    enter image description here

    编辑3 :正在尝试解决 “请在应用程序设置中设置QnAKnowledgebaseId、QnAAuthKey和QnAEndpointHostName(如果适用)。了解如何在 https://aka.ms/qnaabssetup “。” .基本QnAMakerDialog。到目前为止,cs(qnaAuthKey、qnaKBId和endpointHostName的第一个实例都有属于它们的值,但为了安全起见,我在这里删除了它们):

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    
    using Microsoft.Bot.Builder.Azure;
    using Microsoft.Bot.Builder.Dialogs;
    using Microsoft.Bot.Builder.CognitiveServices.QnAMaker;
    using Microsoft.Bot.Connector;
    using System.Configuration;
    namespace Microsoft.Bot.Sample.QnABot
    {
        [Serializable]
        public class RootDialog : IDialog<object>
        {
            public async Task StartAsync(IDialogContext context)
            {
                /* Wait until the first message is received from the conversation and call MessageReceviedAsync 
                *  to process that message. */
                context.Wait(this.MessageReceivedAsync);
            }
    
            private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
            {
                /* When MessageReceivedAsync is called, it's passed an IAwaitable<IMessageActivity>. To get the message,
                 *  await the result. */
                var message = await result;
    
                var qnaAuthKey = GetSetting("");
                var qnaKBId = ConfigurationManager.AppSettings[""];
                var endpointHostName = ConfigurationManager.AppSettings[""];
    
                // QnA Subscription Key and KnowledgeBase Id null verification
                if (!string.IsNullOrEmpty(qnaAuthKey) && !string.IsNullOrEmpty(qnaKBId))
                {
                    // Forward to the appropriate Dialog based on whether the endpoint hostname is present
                    if (string.IsNullOrEmpty(endpointHostName))
                        await context.Forward(new BasicQnAMakerPreviewDialog(), AfterAnswerAsync, message, CancellationToken.None);
                    else
                        await context.Forward(new BasicQnAMakerDialog(), AfterAnswerAsync, message, CancellationToken.None);
                }
                else
                {
                    await context.PostAsync("Please set QnAKnowledgebaseId, QnAAuthKey and QnAEndpointHostName (if applicable) in App Settings. Learn how to get them at https://aka.ms/qnaabssetup.");
                }
    
            }
    
            private async Task AfterAnswerAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
            {
                // wait for the next user message
                context.Wait(MessageReceivedAsync);
            }
    
            public static string GetSetting(string key)
            {
                var value = ConfigurationManager.AppSettings[key];
                if (String.IsNullOrEmpty(value) && key == "QnAAuthKey")
                {
                    value = ConfigurationManager.AppSettings["QnASubscriptionKey"]; // QnASubscriptionKey for backward compatibility with QnAMaker (Preview)
                }
                return value;
            }
        }
    
        // Dialog for QnAMaker Preview service
        [Serializable]
        public class BasicQnAMakerPreviewDialog : QnAMakerDialog
        {
            // Go to https://qnamaker.ai and feed data, train & publish your QnA Knowledgebase.
            // Parameters to QnAMakerService are:
            // Required: subscriptionKey, knowledgebaseId, 
            // Optional: defaultMessage, scoreThreshold[Range 0.0 – 1.0]
            public BasicQnAMakerPreviewDialog() : base(new QnAMakerService(new QnAMakerAttribute(RootDialog.GetSetting("QnAAuthKey"), ConfigurationManager.AppSettings["QnAKnowledgebaseId"], "No good match in FAQ.", 0.5)))
            { }
        }
    
        // Dialog for QnAMaker GA service
        [Serializable]
        public class BasicQnAMakerDialog : QnAMakerDialog
        {
            // Go to https://qnamaker.ai and feed data, train & publish your QnA Knowledgebase.
            // Parameters to QnAMakerService are:
            // Required: qnaAuthKey, knowledgebaseId, endpointHostName
            // Optional: defaultMessage, scoreThreshold[Range 0.0 – 1.0]
            public BasicQnAMakerDialog() : base(new QnAMakerService(new QnAMakerAttribute(RootDialog.GetSetting("QnAAuthKey"), ConfigurationManager.AppSettings["QnAKnowledgebaseId"], "Desculpe, não entendi muito bem sua pergunta... Poderia refazê-la de forma diferente? Caso já tenha tentado, talvez eu ainda não saiba como responder sua dúvida.", 0.3, 1, ConfigurationManager.AppSettings["QnAEndpointHostName"])))
            { }
    
        }
    }
    
    2 回复  |  直到 8 年前
        1
  •  4
  •   Ashwin Kumar    8 年前

    正如错误所述,这里的问题是, AzureWebJobsStorage 在中找不到 web.config 文件要解决您的问题,请在azure portal中导航到您的机器人,然后单击左侧刀片上的应用程序设置。在那里,您将找到一个按键设置 AzureWebJobs存储 enter image description here 复制设置值并将其粘贴到 网状物配置 文件格式:

    <configuration>
      <appSettings>
        <!-- update these with your BotId, Microsoft App Id and your Microsoft App Password-->
        <add key="BotId" value="YourBotId" />
       <add key="MicrosoftAppId" value="" />
       <add key="MicrosoftAppPassword" value="" />
        <add key="QnaSubscriptionKey" value="" />
        <add key="QnaKnowledgebaseId" value="" />
        <add key="AzureWebJobsStorage" value="copied value from azure portal" />
      </appSettings>
    

    更新时间:

    要回答您在评论中提出的进一步问题,

    我被重定向到浏览器中的一个空白页,地址为localhost:3984,还有一个可以阅读QnABot模板的文本,后面是一些链接

    表示bot现在工作正常,实际上是预期的行为。 要在本地测试bot,您需要使用 Bot Emulator .按照链接中提到的步骤测试bot。你也可以通过 bot framework 链接,因为这将使您更清楚地了解Microsoft Bot框架。

    更新2:

    根据您发布的屏幕截图,我认为您已经更改了 Global.asax 文件 注册代码 TableBotDataStore 应该是

    var store = new TableBotDataStore(ConfigurationManager.AppSettings["AzureWebJobsStorage"]); 
    

    这一点都没有变化。

    其次,正如韩飞所说:

    这个 Utils.GetAppSetting(string key) 方法适用于Azure上运行的机器人程序,前提是您要在本地运行机器人程序并从web访问设置。配置文件,您可以使用 ConfigurationManager.AppSettings[“your_key”] 替换 Utils.GetAppSetting(“your_key”) 在你的QnAMakerDialog中。

    第二个屏幕截图显示您仍然有 UTIL。GetAppSetting(您的\u键) 在代码中。将其替换为:

    var qnaKBId = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];
    

    其他地方也是如此。

        2
  •  1
  •   Fei Han    8 年前

    错误系统。ArgumentNullException:'值不能为null。

    正如Ashwin Kumar提到的,您应该包括 "AzureWebJobsStorage" 在您的web中。bot应用程序的配置文件。

    系统FormatException:“设置的格式必须为“name=value”。

    请检查是否获得值 ConfigurationManager.AppSettings["AzureWebJobsStorage"] 并传递一个有效的连接字符串来启动TableBotDataStore,而不仅仅是传递密钥 “AzureWebJobsStorage”

    enter image description here

    我需要在Bot Framework Emulator(使用V4)中进行一些更改和测试,为此,下载并在本地运行我的Bot

    这个 Utils.GetAppSetting(string key) method 适用于Azure上运行的机器人程序,如果您希望在本地运行机器人程序并从web访问设置。配置文件,您可以使用 ConfigurationManager。AppSettings[您的\u密钥] 替换 UTIL。GetAppSetting(您的密钥) 在QnAMakerDialog中,如下所示:

    //var qnaKBId = Utils.GetAppSetting("QnAKnowledgebaseId");
    var qnaKBId = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];