问题
I have been following the tutorial (Bot Framework Integrate Composer Into Skill Project) to integrate composer dialogs with a skill project. This includes composer created dialogs which call a skill. I am running into the exception "Value cannot be null. (Parameter 'uriString')" when calling the skill.
I ran into various other issues when setting this up, as outlined here Previous Issues, which have been resolved though I had to do a work around to get the settings to work. I now need to determine why the configuration settings are not resolving.
To recreate the issue use the "skill-setting-issue" branch of the repo Git Repo
Prerequisites
Install Bot Emulator:Bot Emulator Install Instructions
Open the solution file in visual studio Integrate-Composer-Dialog-Using-Skill.sln
Put a breakpoint on line 79 of DefaultAdapter.cs - this is where the error can be seen
Start debugging the project
Open Bot Emulator
Connect to the bot: http://localhost:3978/api/messages
Type "Greeting"
Bot should respond with "Hello, I have recognized that you said greeting" - This means that the composer dialog integration is working as expected.
Type "Skill"
The breakpoint on line 79 of DefaultAdapter.cs should trigger giving details of the error.
The error seems to be occurring because the settings values within Composer-With-Skill.dialog between line 52 & 57 cannot be resolved.
"botId": "=settings.MicrosoftAppId",
"skillHostEndpoint": "=settings.skillHostEndpoint",
"connectionName": "=settings.connectionName",
"allowInterruptions": true,
"skillEndpoint": "=settings.skill['integrateComposerDialogUsingSkill'].endpointUrl",
"skillAppId": "=settings.skill['integrateComposerDialogUsingSkill'].msAppId",
If I replace the portions which use =settings.... with actual values then the application works (see master branch for code which has that setup).
e.g.
"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",
Note that botId & connectionName are not used so do not cause runtime errors.
These values should be retrieved from ComposerDialogs\settings\appsettings.json line 67 through 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 has been configured to be a setting file in the application in Startup.cs line 51 as per the tutorial I am following.
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();
I'm not sure why the variables in the Composer-With-Skill.dialog file are not being resolved by the settings values in ComposerDialogs\settings\appsettings.json
The error occurs on line 156 of file Microsoft.Bot.Builder.Dialogs.Adaptive.BeginSkill in method BeginDialogAsync Bot Builder Git - BeginSkill.cs when the code tries to populate the DialogOptions.SkillHostEndpoint value.
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);
Edit: Putting the value, "skillHostEndpoint": "http://localhost:3978/api/skills", in the main appsettings.json file causes the code to work.
Edit: moving ComposerDialogs/settings/appsettings.json up to the main folder & renaming to appsettings-composer.json & adjusting the startup.cs does not help
Edit: removing .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) does not prevent the app settings from being available in BeginSkill.cs. So, this seems to indicate that configuring the builder in Startup.cs has no impact on the available settings.
回答1:
Determined that the IConfiguration instance which was configured & created in the constructor of Startup.cs was not being used when dependency injection was happening on IConfiguration. This was causing the new configuration files added not to be available.
Added
services.AddSingleton<IConfiguration>(Configuration);
To ConfigureServices of Startup.cs so that the correct object would be retrieved & the values would be available.
skill-setting-issue branch of the Git Repo has been updated to reflect this.
This Post helped to determine the issue.
来源:https://stackoverflow.com/questions/65363853/bot-framework-v4-value-cannot-be-null-parameter-uristring