Skip to content

Remove duplicated profiles block from empty C# AppHost aspire.config.json#17781

Merged
mitchdenny merged 1 commit into
mainfrom
mitchdenny/fix-duplicate-config-empty-template
Jun 2, 2026
Merged

Remove duplicated profiles block from empty C# AppHost aspire.config.json#17781
mitchdenny merged 1 commit into
mainfrom
mitchdenny/fix-duplicate-config-empty-template

Conversation

@mitchdenny
Copy link
Copy Markdown
Member

Description

Fixes #17660.

The embedded CLI template src/Aspire.Cli/Templating/Templates/empty-apphost/aspire.config.json shipped a profiles block that duplicated the content already in apphost.run.json. The canonical template at src/Aspire.ProjectTemplates/templates/aspire-apphost-singlefile/aspire.config.json intentionally has no profiles (per @DamianEdwards in the issue): aspire run / dotnet run apphost.cs / C# Dev Kit honor apphost.run.json when present, so aspire.config.json for the C# Empty template should only carry:

{ "appHost": { "path": "apphost.cs" } }

This was a regression introduced in the 13.4 cycle. In 13.3.5 only aspire.config.json was emitted; once apphost.run.json was added the embedded template was not trimmed to remove the now-duplicated profiles.

Changes

  • src/Aspire.Cli/Templating/Templates/empty-apphost/aspire.config.json — removed the profiles block.
  • tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs — three tests previously asserted the duplicated content:
    • The two …EmitsAppHostRunJson… tests now assert aspire.config.json has no profiles block and that it pins appHost.path = "apphost.cs", while apphost.run.json carries the launch URLs (plain localhost and dev.localhost variants).
    • The …PromptsForLocalhostTld… test now asserts the dev-localhost URL lives in apphost.run.json and is absent from aspire.config.json.
    • Removed the obsolete AssertHttpsApplicationUrlMatches helper.

Safety

  • DotNetAppHostProject reads apphost.run.json first and only falls back to aspire.config.json#profiles when apphost.run.json is missing, so removing profiles from a template that ships apphost.run.json is safe at runtime.
  • ApplyLocalhostTldToScaffoldedRunProfileAsync only runs for non-C# scaffolded templates (TypeScript / Python); the C# path applies tokens via ApplyAllTokens to all files including apphost.run.json, so the localhost-TLD substitution still lands in the right file.
  • E2E coverage already exists: tests/Aspire.Cli.EndToEnd.Tests/EmptyAppHostTemplateTests.CreateAndRunEmptyAppHostProject runs aspire new (C# Empty) → aspire start --format json → curls the dashboard URL for HTTP 200 → aspire stop. If the new layout broke startup it would catch it.
  • Existing projects on disk are not modified; this only affects newly-scaffolded projects.

Tested

  • All 77 NewCommandTests pass locally.
  • All 50 NewCommandTemplateConfigPersistenceTests + NewCommandChannelResolutionTests pass locally.

Microsoft Reviewers: Open in CodeFlow

…json

The embedded CLI template src/Aspire.Cli/Templating/Templates/empty-apphost/aspire.config.json
shipped a profiles block that duplicated apphost.run.json. The canonical template in
src/Aspire.ProjectTemplates/templates/aspire-apphost-singlefile/aspire.config.json
intentionally has no profiles (per Damian's design): aspire run / dotnet run apphost.cs
honor apphost.run.json when present, so aspire.config.json for the C# Empty template
should only carry { "appHost": { "path": "apphost.cs" } }.

Updated NewCommandTests to:
- assert that aspire.config.json has no profiles block and pins appHost.path = apphost.cs
- assert that apphost.run.json carries the launch URLs (plain localhost and dev.localhost variants)
- drop the now-unused AssertHttpsApplicationUrlMatches helper

Fixes #17660

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17781

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17781"

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

CLI E2E Tests unknown — 110 passed, 0 failed, 2 unknown (commit 2e47d53)

View all recordings
Status Test Recording Job Artifacts
AddPackageInteractiveWhileAppHostRunningDetached Recording #78793326181 Logs
AddPackageWhileAppHostRunningDetached Recording #78793326181 Logs
AgentCommands_AllHelpOutputs_AreCorrect Recording #78793326426 Logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording #78793326426 Logs
AgentInitCommand_MigratesDeprecatedConfig Recording #78793326426 Logs
AgentInitCommand_NonInteractive_BundleOnlySkillsBeyondCliCatalog_AreInstallable Recording #78793326426 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording #78793326493 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording #78793326493 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording #78793326493 Logs
AllPublishMethodsBuildDockerImages Recording #78793326209 Logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording #78793326231 Logs
AspireAddPackageVersionToDirectoryPackagesProps Recording #78793326482 Logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording #78793326729 Logs
AspireInitWithExistingAppHostDirRecreatesMissingNuGetConfigAndPreservesFiles Recording #78793326112 Logs
AspireInitWithSolutionFileGeneratesAppHostThatBuildsAgainstChannelHive Recording #78793326112 Logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording #78793326540 Logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording #78793326482 Logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording #78793326482 Logs
Banner_DisplayedOnFirstRun Recording #78793326776 Logs
Banner_DisplayedWithExplicitFlag Recording #78793326776 Logs
Banner_NotDisplayedWithNoLogoFlag Recording #78793326776 Logs
CertificatesClean_RemovesCertificates Recording #78793326291 Logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording #78793326291 Logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording #78793326291 Logs
ConfigSetGet_CreatesNestedJsonFormat Recording #78793326764 Logs
CreateAndRunAspireStarterProject Recording #78793326753 Logs
CreateAndRunAspireStarterProjectWithBundle Recording #78793326774 Logs
CreateAndRunEmptyAppHostProject Recording #78793326173 Logs
CreateAndRunJavaEmptyAppHostProject Recording #78793326714 Logs
CreateAndRunJsReactProject Recording #78793326740 Logs
CreateAndRunPolyglotAppHostWithDevLocalhostUrls Recording #78793326753 Logs
CreateAndRunPythonReactProject Recording #78793326137 Logs
CreateAndRunTypeScriptEmptyAppHostProject Recording #78793326777 Logs
CreateAndRunTypeScriptStarterProject Recording #78793326141 Logs
CreateJavaAppHostWithViteApp Recording #78793326397 Logs
CreateTypeScriptAppHostWithViteApp_AllowsGuestAppPackageManagerToDiffer Recording #78793326745 Logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording #78793326745 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording #78793326216 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording #78793326216 Logs
DashboardRunWithOtelTracesReturnsNoTraces Recording #78793326216 Logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording #78793326216 Logs
DeployK8sBasicApiService Recording #78793326134 Logs
DeployK8sWithExternalHelmChart Recording #78793326490 Logs
DeployK8sWithGarnet Recording #78793326743 Logs
DeployK8sWithMongoDB Recording #78793326192 Logs
DeployK8sWithMySql Recording #78793326346 Logs
DeployK8sWithPostgres Recording #78793326649 Logs
DeployK8sWithRabbitMQ Recording #78793326780 Logs
DeployK8sWithRedis Recording #78793326760 Logs
DeployK8sWithSqlServer Recording #78793326750 Logs
DeployK8sWithValkey Recording #78793326349 Logs
DeployTypeScriptAppToKubernetes Recording #78793326788 Logs
DescribeCommandResolvesReplicaNames Recording #78793326294 Logs
DescribeCommandShowsRunningResources Recording #78793326294 Logs
DetachFormatJsonProducesValidJson Recording #78793326156 Logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording #78793326156 Logs
DoPublishAndDeployListStepsWork Recording #78793326639 Logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording #78793326747 Logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording #78793326426 Logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording #78793326443 Logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording #78793326443 Logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording #78793326443 Logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78793326146 Logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording #78793326745 Logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording #78793326764 Logs
GlobalMigration_HandlesMalformedLegacyJson Recording #78793326764 Logs
GlobalMigration_PreservesAllValueTypes Recording #78793326764 Logs
GlobalMigration_SkipsWhenNewConfigExists Recording #78793326764 Logs
GlobalSettings_MigratedFromLegacyFormat Recording #78793326764 Logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78793326146 Logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording #78793326745 Logs
InteractiveCSharpInitCreatesExpectedFiles Recording #78793326674 Logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording #78793326650 Logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording #78793326209 Logs
LatestCliCanStartStableChannelAppHost Recording #78793326753 Logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording #78793326753 Logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording #78793326540 Logs
LogsCommandShowsResourceLogs Recording #78793326655 Logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording #78793326343 Logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording #78793326343 Logs
PsCommandListsRunningAppHost Recording #78793326322 Logs
PsFormatJsonOutputsOnlyJsonToStdout Recording #78793326322 Logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording #78793326338 Logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording #78793326338 Logs
PublishWithDockerComposeServiceCallbackSucceeds Recording #78793326338 Logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording #78793326338 Logs
ResourceCommand_FailedExecution_DisplaysAppHostLogPathAndLogContainsEntries Recording #78793326795 Logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording #78793326795 Logs
RestoreGeneratesSdkFiles Recording #78793326506 Logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording #78793326558 Logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording #78793326558 Logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording #78793326484 Logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording #78793326785 Logs
RunReportsSyntaxErrorsForDotNetAppHost Recording #78793326738 Logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording #78793326738 Logs
SecretCrudOnDotNetAppHost Recording #78793326132 Logs
SecretCrudOnTypeScriptAppHost Recording #78793326393 Logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording #78793326661 Logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording #78793326195 Logs
StartReportsSyntaxErrorsForDotNetAppHost Recording #78793326738 Logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording #78793326738 Logs
StopAllAppHostsFromAppHostDirectory Recording #78793326523 Logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording #78793326169 Logs
StopNonInteractiveSingleAppHost Recording #78793326523 Logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording #78793326681 Logs
StopWithNoRunningAppHostExitsSuccessfully Recording #78793326181 Logs
TypeScriptAppHostRunDoesNotDeadlockWhenLazyOptionsInvokeAsyncCallback Recording #78793326777 Logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording #78793326558 Logs
UpdateProjectChannelToStable_CSharpEmptyAppHost_PreservesAspireConfigChannel Recording #78793326691 Logs
UpdateProjectChannelToStable_CSharpSingleFileInit_PreservesAspireConfigChannel Recording #78793326691 Logs
UpdateProjectChannelToStable_TypeScriptSingleFileInit_PreservesAspireConfigChannel Recording #78793326691 Logs
UpdateProjectChannelToStable_TypeScript_PreviewsStablePackagesAndPreservesChannel Recording #78793326691 Logs

📹 Recordings uploaded automatically from CI run #26736967130

@mitchdenny
Copy link
Copy Markdown
Member Author

PR #17781 Testing Report

PR Information

CLI Version Verification

  • Expected Commit: 2e47d53c
  • Installed Version: 13.5.0-pr.17781.g2e47d53c
  • Status: ✅ Verified — installed CLI matches the PR's head commit.

Changes Analyzed

Files Changed

  • src/Aspire.Cli/Templating/Templates/empty-apphost/aspire.config.json — removed the profiles block; file is now just { "appHost": { "path": "apphost.cs" } }.
  • tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs — three tests updated to assert the new shape; obsolete AssertHttpsApplicationUrlMatches helper removed.

Change Categories

  • CLI changes (embedded template content)
  • Hosting integration changes
  • Dashboard changes
  • Test changes
  • Aspire.ProjectTemplates changes
  • Client/Component changes

Test Scenarios Executed

Scenario 1: Plain aspire new aspire-empty (C#, --localhost-tld false)

Objective: Confirm the generated aspire.config.json no longer carries a profiles block, while apphost.run.json still owns the launch profiles with plain localhost URLs.
Coverage Type: Happy path
Status: ✅ Passed

Steps:

  1. aspire new aspire-empty --name PlainLocalhostApp --output … --language csharp --localhost-tld false --suppress-agent-init --non-interactive
  2. Inspected aspire.config.json and apphost.run.json.

Evidence — aspire.config.json (exact contents):

{
  "appHost": {
    "path": "apphost.cs"
  }
}

No profiles key. Matches the canonical aspire-apphost-singlefile template shape.

Evidence — apphost.run.json (excerpt):

"profiles": {
  "https": {
    "commandName": "Project",
    "applicationUrl": "https://localhost:17289;http://localhost:15256",
    "environmentVariables": { … "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21282" … }
  },
  "http": { … "applicationUrl": "http://localhost:15256" … }
}

Launch profiles present with ://localhost: URLs.

Observations:


Scenario 2: aspire new aspire-empty --localhost-tld true

Objective: Confirm dev.localhost URLs land in apphost.run.json only and that aspire.config.json is identical to the plain case (no host TLD, no profiles).
Coverage Type: Happy path (option variant)
Status: ✅ Passed

Steps:

  1. aspire new aspire-empty --name TldApp --output … --language csharp --localhost-tld true --suppress-agent-init --non-interactive
  2. Inspected both config files.

Evidence — aspire.config.json (exact contents):

{
  "appHost": {
    "path": "apphost.cs"
  }
}

Identical to scenario 1 — no tldapp.dev.localhost reference, no profiles.

Evidence — apphost.run.json (excerpt):

"https": {
  "applicationUrl": "https://tldapp.dev.localhost:17005;http://tldapp.dev.localhost:15276",
  
  "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://tldapp.dev.localhost:21117",
  "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://tldapp.dev.localhost:22296"
}

tldapp.dev.localhost substitution lands correctly in apphost.run.json via the C# template's token-replacement path.

Observations:

  • Localhost-TLD substitution did not regress; it just lives in a single file now instead of two.

Scenario 3: Runtime smoke — aspire start + dashboard reachability + aspire stop

Objective: Confirm aspire start honours the launch profile from apphost.run.json even though aspire.config.json no longer carries one, and that the dashboard is actually reachable.
Coverage Type: Happy path (runtime)
Status: ✅ Passed

Steps:

  1. From the scenario 1 project: aspire start --apphost apphost.cs --format json.
  2. Parsed the emitted JSON for dashboardUrl.
  3. curl -ksSL -o /dev/null -w '%{http_code}' "$dashboardUrl".
  4. aspire stop --apphost apphost.cs.

Evidence — aspire start JSON:

{
  "appHostPath": ".../scenario1/PlainLocalhostApp/apphost.cs",
  "appHostPid": 39627,
  "cliPid": 39517,
  "dashboardUrl": "https://localhost:17289/login?t=2a85971cf034b51961f6113be996f1c6",
  
}

Dashboard bound to port 17289 — exactly the HTTPS port from the apphost.run.json launch profile. This is the key positive signal: with profiles removed from aspire.config.json, the reader correctly used apphost.run.json instead of falling through to hardcoded defaults.

Evidence — dashboard reachability:

dashboard-http-200

Evidence — clean shutdown:

✅ apphost.cs stopped successfully.

Observations:

  • End-to-end happy path works: scaffold → start → dashboard at the expected URL → curl 200 → stop.
  • Equivalent to what the CI E2E test EmptyAppHostTemplateTests.CreateAndRunEmptyAppHostProject validated, but here against the PR build on a real macOS host.

Summary

Scenario Status Notes
1. Plain localhost — file shape ✅ Passed aspire.config.json minimal; apphost.run.json carries profiles
2. Localhost-TLD — file shape ✅ Passed TLD substitution lands in apphost.run.json only
3. Runtime smoke ✅ Passed Dashboard bound at apphost.run.json port, HTTP 200, clean stop

Overall Result

✅ PR VERIFIED

Issue #17660 is fixed. The empty C# AppHost template no longer duplicates launch-profile content across apphost.run.json and aspire.config.json — profiles live only in apphost.run.json, and aspire.config.json is the minimal canonical shape { "appHost": { "path": "apphost.cs" } }. Runtime behavior (aspire start / dashboard reachability) is unaffected.

Recommendations

  • None for this PR.
  • (Out of scope per author) Drift detection between Aspire.Cli/Templating/Templates/empty-apphost/ and Aspire.ProjectTemplates/templates/aspire-apphost-singlefile/ is worth considering separately — that divergence is what allowed this duplication to survive for several months.

@mitchdenny mitchdenny marked this pull request as ready for review June 1, 2026 09:10
Copilot AI review requested due to automatic review settings June 1, 2026 09:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a regression in the embedded Aspire CLI empty C# AppHost template where aspire.config.json redundantly carried a profiles block that is already provided via apphost.run.json (per #17660). The change aligns the embedded CLI template with the canonical single-file AppHost template behavior: aspire.config.json should only point at apphost.cs, while launch profiles live exclusively in apphost.run.json.

Changes:

  • Removed the duplicated profiles block from src/Aspire.Cli/Templating/Templates/empty-apphost/aspire.config.json, leaving only "appHost": { "path": "apphost.cs" }.
  • Updated NewCommandTests to assert that aspire.config.json has no profiles, and that URLs/profiles exist in apphost.run.json (including dev.localhost behavior).
  • Removed the now-obsolete test helper that compared HTTPS URLs between the two files.
Show a summary per file
File Description
src/Aspire.Cli/Templating/Templates/empty-apphost/aspire.config.json Removes redundant launch profile configuration so the template relies on apphost.run.json as the single source of launch profiles.
tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs Updates assertions to validate the new split of responsibilities: minimal aspire.config.json and launch URLs/profiles in apphost.run.json.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
Member

@JamesNK JamesNK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean fix. The template change correctly removes the duplicated profiles block that's already in apphost.run.json, and the tests properly validate the new contract from multiple angles (plain localhost, dev.localhost TLD, and prompted TLD paths). No issues found.

@mitchdenny mitchdenny merged commit 47eb2f6 into main Jun 2, 2026
326 checks passed
@mitchdenny mitchdenny deleted the mitchdenny/fix-duplicate-config-empty-template branch June 2, 2026 03:55
@mitchdenny
Copy link
Copy Markdown
Member Author

/backport to release/13.4

@microsoft-github-policy-service microsoft-github-policy-service Bot modified the milestones: 13.4.x, 13.5 Jun 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Started backporting to release/13.4 (link to workflow run)

aspire-repo-bot Bot added a commit to microsoft/aspire.dev that referenced this pull request Jun 2, 2026
The empty C# AppHost template (created with `aspire new`) stores launch
profiles in `apphost.run.json`, not in `aspire.config.json`. The
`aspire.config.json` for this template only contains the `appHost.path`
reference pointing at `apphost.cs`.

Update the AppHost configuration page to distinguish between:
- Project-based AppHosts: profiles in `Properties/launchSettings.json`
- File-based AppHosts: profiles in `apphost.run.json`, with
  `aspire.config.json` holding only the entry-point reference

This aligns the documentation with the fix in microsoft/aspire#17781,
which corrected a regression where the file-based template was
incorrectly emitting a duplicate `profiles` block in `aspire.config.json`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aspire-repo-bot
Copy link
Copy Markdown
Contributor

Pull request created: #1176

Generated by PR Documentation Check

@aspire-repo-bot
Copy link
Copy Markdown
Contributor

📝 Documentation has been drafted in microsoft/aspire.dev#1176 targeting release/13.4.

Updated src/frontend/src/content/docs/app-host/configuration.mdx to distinguish between project-based C# AppHosts (profiles in launchSettings.json) and file-based C# AppHosts (profiles in apphost.run.json, with aspire.config.json holding only the entry-point reference). Added code examples for both files and a note explaining the runtime behavior.

Note

This draft PR needs human review before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[AspireE2E] Some content are duplicate in the apphost.run.json and aspire.config.json files of Aspire Empty C# (.NET) project

3 participants