Bot Framework V4:值不能为空。 (参数'uriString')

Bot Framework V4: Value cannot be null. (Parameter 'uriString')

我一直在按照教程 (Bot Framework Integrate Composer Into Skill Project) 将作曲家对话框与技能项目集成。这包括作曲家创建的调用技能的对话框。我运行在调用技能时出现异常“值不能为空。(参数'uriString')”。

我 运行 在设置时遇到了各种其他问题,如此处所述 ,尽管我必须解决这些问题才能使设置正常工作,但这些问题已得到解决。我现在需要确定配置设置未解析的原因。

要重现问题,请使用 repo Git Repo

的“技能设置问题”b运行ch

先决条件

安装机器人模拟器:Bot Emulator Install Instructions

在visual studio Integrate-Composer-Dialog-Using-Skill.sln

中打开解决方案文件

在DefaultAdapter.cs的第79行打断点-这是可以看到错误的地方

开始调试项目

打开机器人模拟器

连接到机器人:http://localhost:3978/api/messages

输入“问候语”

Bot 应该回应“你好,我知道你说了问候语”——这意味着作曲家对话框集成正在按预期工作。

键入“技能”

DefaultAdapter.cs 第 79 行的断点应该触发给出错误的详细信息。

错误似乎是因为 Composer-With-Skill.dialog 中第 52 和 57 行之间的设置值无法解析。

"botId": "=settings.MicrosoftAppId",
"skillHostEndpoint": "=settings.skillHostEndpoint",
"connectionName": "=settings.connectionName",
"allowInterruptions": true,
"skillEndpoint": "=settings.skill['integrateComposerDialogUsingSkill'].endpointUrl",
"skillAppId": "=settings.skill['integrateComposerDialogUsingSkill'].msAppId",

如果我将使用 =settings.... 的部分替换为实际值,则应用程序可以正常工作(有关具有该设置的代码,请参阅 master b运行ch)。

例如

"botId": "=settings.MicrosoftAppId",
"skillHostEndpoint": "http://localhost:3978/api/skills",
"connectionName": "=settings.connectionName",
"allowInterruptions": true,
"skillEndpoint": "http://localhost:3978/api/echo/messages",
"skillAppId": "00000000-0000-0000-0000-000000000000",

请注意,未使用 botId 和 connectionName,因此不会导致运行时错误。

应从 ComposerDialogs\settings\appsettings.json 第 67 行到第 79 行检索这些值。

  "skill": {
    "integrateComposerDialogUsingSkill": {
      "endpointUrl": "http://localhost:3978/api/echo/messages",
      "msAppId": "00000000-0000-0000-0000-000000000000"
    }
  },
  "defaultLanguage": "en-us",
  "languages": [
    "en-us"
  ],
  "customFunctions": [],
  "skillHostEndpoint": "http://localhost:3978/api/skills"
}

ComposerDialogs\settings\appsettings.json 已根据我正在关注的教程在 Startup.cs 第 51 行中配置为应用程序中的设置文件。

public class Startup
{
    public Startup(IWebHostEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddJsonFile("cognitivemodels.json", optional: true)
            .AddJsonFile($"cognitivemodels.{env.EnvironmentName}.json", optional: true)
            //from instructions: https://microsoft.github.io/botframework-solutions/skills/handbook/experimental-add-composer/
            .AddJsonFile($"ComposerDialogs\settings\appsettings.json", optional: true)
            .AddEnvironmentVariables();

我不确定为什么 Composer-With-Skill.dialog 文件中的变量没有被 ComposerDialogs\settings\appsettings.json

中的设置值解析

错误发生在方法 BeginDialogAsync 文件 Microsoft.Bot.Builder.Dialogs.Adaptive.BeginSkill 的第 156 行 Bot Builder Git - BeginSkill.cs 当代码尝试填充 DialogOptions.SkillHostEndpoint 值时。

public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
        {
            if (Disabled != null && Disabled.GetValue(dc.State))
            {
                return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
            }

            // Update the dialog options with the runtime settings.
            DialogOptions.BotId = BotId.GetValue(dc.State);
            DialogOptions.SkillHostEndpoint = new Uri(SkillHostEndpoint.GetValue(dc.State));
            DialogOptions.ConversationIdFactory = dc.Context.TurnState.Get<SkillConversationIdFactoryBase>() ?? throw new NullReferenceException("Unable to locate SkillConversationIdFactoryBase in HostContext");
            DialogOptions.SkillClient = dc.Context.TurnState.Get<BotFrameworkClient>() ?? throw new NullReferenceException("Unable to locate BotFrameworkClient in HostContext");
            DialogOptions.ConversationState = dc.Context.TurnState.Get<ConversationState>() ?? throw new NullReferenceException($"Unable to get an instance of {nameof(ConversationState)} from TurnState.");
            DialogOptions.ConnectionName = ConnectionName.GetValue(dc.State);

编辑:将值“skillHostEndpoint”:“http://localhost:3978/api/skills”放入主 appsettings.json 文件中会使代码正常工作。

编辑:将 ComposerDialogs/settings/appsettings.json 移动到主文件夹并重命名为 appsettings-composer.json 并调整 startup.cs 没有帮助

编辑:删除 .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 不会阻止应用程序设置在 BeginSkill.cs 中可用。因此,这似乎表明在 Startup.cs 中配置构建器对可用设置没有影响。

确定在 Startup.cs 的构造函数中配置和创建的 IConfiguration 实例在 IConfiguration 上发生依赖注入时未被使用。这导致添加的新配置文件不可用。

已添加

services.AddSingleton<IConfiguration>(Configuration);

配置 Startup.cs 的服务,以便检索正确的对象并提供值。

Git Repo 的技能设置问题分支已更新以反映这一点。

有助于确定问题。