C# Azure Bot Framework仿真程序错误-System.ArgumentNullException:值不能为null
我需要一些帮助。我是Azure的机器人框架开发新手,几周前使用QnA KB创建了我的第一个聊天机器人。无论如何,我设法在Azure的门户中创建了bot,它工作得非常好。但我需要在Bot Framework Emulator(使用V4)中进行一些修改和测试,为此,下载并在本地运行我的Bot 我按照Azure的指示下载了bot的.zip文件,并使用Visual Studio 2017作为IDE对其进行了初始化。但是,当我点击“调试”按钮时,程序尝试连接到localhost:3984C# Azure Bot Framework仿真程序错误-System.ArgumentNullException:值不能为null,c#,azure,botframework,C#,Azure,Botframework,我需要一些帮助。我是Azure的机器人框架开发新手,几周前使用QnA KB创建了我的第一个聊天机器人。无论如何,我设法在Azure的门户中创建了bot,它工作得非常好。但我需要在Bot Framework Emulator(使用V4)中进行一些修改和测试,为此,下载并在本地运行我的Bot 我按照Azure的指示下载了bot的.zip文件,并使用Visual Studio 2017作为IDE对其进行了初始化。但是,当我点击“调试”按钮时,程序尝试连接到localhost:3984 using Au
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);
}
}
}
因此,我无法在bot框架模拟器中测试我的bot。既然我对C#很陌生,谁能帮我解决这个问题
编辑:以下是代码的web.config部分,仅删除敏感数据:
<?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=\"Web\" /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>
编辑3:尝试解决“请在应用程序设置中设置QnAKnowledgebaseId、QnAAuthKey和QnAEndpointHostName(如果适用)。了解如何在获取它们。”。到目前为止,基本的QnAMakerDialog.cs(qnaAuthKey、qnaKBId和endpointHostName的第一个实例都有属于它们的值,但为了安全起见,我在这里删除了它们):
使用系统;
使用系统线程;
使用System.Threading.Tasks;
使用Microsoft.Bot.Builder.Azure;
使用Microsoft.Bot.Builder.Dialogs;
使用Microsoft.Bot.Builder.CognitiveServices.QnAMaker;
使用Microsoft.Bot.Connector;
使用系统配置;
命名空间Microsoft.Bot.Sample.QnABot
{
[可序列化]
公共类RootDialog:IDialog
{
公共异步任务StartAsync(IDialogContext上下文)
{
/*等待,直到从对话中收到第一条消息,然后调用MessageReceviedAsync
*来处理这个消息*/
context.Wait(this.MessageReceivedAsync);
}
专用异步任务消息ReceivedAsync(IDialogContext上下文,IAwaitable结果)
{
/*调用MessageReceivedAsync时,会传递一个IAwaitable。要获取消息,
*等待结果*/
var消息=等待结果;
var qnaAuthKey=GetSetting(“”);
var qnaKBId=ConfigurationManager.AppSettings[“”];
var endpointHostName=ConfigurationManager.AppSettings[“”);
//QnA订阅密钥和知识库Id空验证
如果(!string.IsNullOrEmpty(qnaAuthKey)和&!string.IsNullOrEmpty(qnaKBId))
{
//根据端点主机名是否存在转发到相应的对话框
if(string.IsNullOrEmpty(endpointHostName))
wait context.Forward(新的basicqlnamakerprevewdialog(),AfterAnswerAsync,message,CancellationToken.None);
其他的
wait context.Forward(new BasicQnAMakerDialog(),AfterAnswerAsync,message,CancellationToken.None);
}
其他的
{
等待context.PostAsync(“请在应用程序设置中设置QnAKnowledgebaseId、QnAAuthKey和QnAEndpointHostName(如果适用)。了解如何在https://aka.ms/qnaabssetup.");
}
}
应答异步后的专用异步任务(IDialogContext上下文,IAwaitable结果)
{
//等待下一条用户消息
Wait(MessageReceivedAsync);
}
公共静态字符串设置(字符串键)
{
var value=ConfigurationManager.AppSettings[key];
if(String.IsNullOrEmpty(value)和&key==“QnAAuthKey”)
{
value=ConfigurationManager.AppSettings[“QnASubscriptionKey”];//QnASubscriptionKey与QnAMaker的向后兼容性(预览)
}
返回值;
}
}
//QnAMaker预览服务对话框
[可序列化]
公共类BasicQnAMakerPreviewDialog:QnAMakerDialog
{
//去https://qnamaker.ai 并提供数据、培训和发布您的QnA知识库。
//QNAMAKERSERSERVICE的参数为:
//必需:subscriptionKey、knowledgebaseId、,
//可选:defaultMessage,scoreThreshold[范围0.0–1.0]
public BasicQnAMakerPreviewDialog():base(新的QnAMakerService(新的QnAMakerAttribute(RootDialog.GetSetting(“QnAAuthKey”)、ConfigurationManager.AppSettings[“QnAKnowledgebaseId”]、“常见问题解答中没有很好的匹配”,0.5)))
{ }
}
//QnAMaker GA服务对话框
[可序列化]
公共类BasicQnAMakerDialog:QnAMakerDialog
{
//去https://qnamaker.ai 并提供数据、培训和发布您的QnA知识库。
//QNAMAKERSERSERVICE的参数为:
//必需:qnaAuthKey、knowledgebaseId、endpointHostName
//可选:defaultMessage,scoreThreshold[范围0.0–1.0]
public BasicQnAMakerDialog():base(新的QnAMakerService(新的QnAMakerAttribute)(RootDialog.GetSetting(“QnAAuthKey”)、ConfigurationManager.AppSettings[“QnAKnowledgebaseId”],“Desculpe,não entendi muito bem sua pergunta…Poderia Refrazè-la de forma differentient?Caso játenha tentado,talvez eu ainda não saiba como responder sua dúvida.”,0.3,1,ConfigurationManager.AppSettings[“QnAEndpointHostName”]))
{ }
}
}
正如错误所述,这里的问题是,azurewebjobstorage
无法在web.config
文件中找到。要解决您的问题,请在azure portal中导航到您的机器人,然后单击左侧刀片服务器上的应用程序设置。在这里,您可以找到一个带有键azurewebjobstorage
的设置。
复制设置值并将其粘贴到web.config
文件中,如下所示:
<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>
这一点没有任何变化。
第二,正如韩非所说:
Utils.GetAppSetting(字符串键)
方法适用于运行在Azure上的机器人程序,如果
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"])))
{ }
}
}
<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>
var store = new TableBotDataStore(ConfigurationManager.AppSettings["AzureWebJobsStorage"]);
var qnaKBId = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];
//var qnaKBId = Utils.GetAppSetting("QnAKnowledgebaseId");
var qnaKBId = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];