Repository navigation
Fix port replacers in templates to prevent unintended replacements - #65165
Conversation
Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com>
…rect replacements Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR constrains Kestrel port replacements in project templates so they only occur in URL contexts, preventing unintended modification of numeric literals (e.g., in bootstrap.bundle.js) when random ports are assigned.
Changes:
- Added
onlyIfconditions tokestrelHttpPortReplacerandkestrelHttpsPortReplaceracross all relevant web project templates so replacements only occur when the port is preceded bylocalhost:. - Left IIS port replacers unchanged (still global), after confirming their literal values (e.g.,
8080,44300) are not used elsewhere in template content. - Normalized a minor JSON formatting issue in
GrpcService-CSharp("NativeAot": {spacing).
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/ProjectTemplates/Web.ProjectTemplates/content/WebApiAot-CSharp/.template.config/template.json | Adds onlyIf on kestrelHttpPortReplacer so HTTP port substitution only happens in localhost: URL contexts for the native AOT Web API template. |
| src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-FSharp/.template.config/template.json | Constrains both HTTP and HTTPS Kestrel port replacers with onlyIf conditions to avoid global numeric replacements. |
| src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json | Mirrors the F# Web API changes for C#, adding onlyIf constraints to Kestrel HTTP/HTTPS port replacers. |
| src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/.template.config/template.json | Adds onlyIf to Kestrel HTTP/HTTPS port replacers so only localhost: URLs are affected in the starter F# web template. |
| src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json | Same onlyIf constraints added for the C# starter web template’s Kestrel HTTP/HTTPS port replacers. |
| src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json | Restricts Kestrel HTTP/HTTPS port replacements to URL contexts via onlyIf to avoid corrupting other numeric values. |
| src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json | Adds onlyIf to Kestrel HTTP/HTTPS port replacers and tidies JSON spacing for the NativeAot symbol. |
| src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-FSharp/.template.config/template.json | Constrains Kestrel HTTP/HTTPS port replacers with onlyIf so only localhost: URLs are rewritten in the empty F# template. |
| src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json | Same Kestrel HTTP/HTTPS onlyIf constraints applied for the empty C# template. |
| src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json | Adds onlyIf to Kestrel HTTP/HTTPS replacers for the Blazor WebAssembly components template to avoid global numeric replacements. |
| src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/.template.config/template.json | Adds onlyIf to Kestrel HTTP/HTTPS port replacers (the source of the reported issue), constraining replacements to localhost: URLs and preventing corruption of bundled JS numeric literals. |
| "replaces": "5500", | ||
| "onlyIf": [{ | ||
| "after": "localhost:" | ||
| }] | ||
| }, |
There was a problem hiding this comment.
These new onlyIf constraints change how the template engine performs port substitutions, but there doesn't appear to be a regression test asserting that ports are only replaced in URL contexts (for example, ensuring numeric constants in bootstrap.bundle.js are not modified). Consider adding a template test that generates a Blazor WebAssembly project, reads wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js, and verifies that known numeric literals (such as the carousel interval value) remain unchanged and do not get replaced with the assigned Kestrel HTTP/HTTPS ports.
The dynamic port symbols (webHttpPortReplacer, apiServiceHttpPortReplacer,
appHostHttpPortReplacer, etc.) used a bare numeric "replaces" value, so the
template engine substituted that number everywhere in generated content, not
just in launchSettings.json. Since the default ports (5000, 7000, 5301, 7301,
15000, 17000, 19000, 20000, 21000, 22000) also occur as plain numeric literals
in vendored files such as wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
(e.g. carousel interval: 5000), those files ended up with churned values that
differ between generated projects, making diffs across template runs noisy.
Add "onlyIf": [{"after": "localhost:"}] to each port replacer so substitution
only fires in "localhost:<port>" contexts, matching the fix already applied
upstream for the same class of bug (dotnet/aspnetcore#65165, dotnet/sdk#48811).
Fixes #20030
The dynamic port symbols (webHttpPortReplacer, apiServiceHttpPortReplacer,
appHostHttpPortReplacer, etc.) used a bare numeric "replaces" value, so the
template engine substituted that number everywhere in generated content, not
just in launchSettings.json. Since the default ports (5000, 7000, 5301, 7301,
15000, 17000, 19000, 20000, 21000, 22000) also occur as plain numeric literals
in vendored files such as wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
(e.g. carousel interval: 5000), those files ended up with churned values that
differ between generated projects, making diffs across template runs noisy.
Add "onlyIf": [{"after": "localhost:"}] to each port replacer so substitution
only fires in "localhost:<port>" contexts, matching the fix already applied
upstream for the same class of bug (dotnet/aspnetcore#65165, dotnet/sdk#48811).
Fixes #20030
The dynamic port symbols (webHttpPortReplacer, apiServiceHttpPortReplacer,
appHostHttpPortReplacer, etc.) used a bare numeric "replaces" value, so the
template engine substituted that number everywhere in generated content, not
just in launchSettings.json. Since the default ports (5000, 7000, 5301, 7301,
15000, 17000, 19000, 20000, 21000, 22000) also occur as plain numeric literals
in vendored files such as wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
(e.g. carousel interval: 5000), those files ended up with churned values that
differ between generated projects, making diffs across template runs noisy.
Add "onlyIf": [{"after": "localhost:"}] to each port replacer so substitution
only fires in "localhost:<port>" contexts, matching the fix already applied
upstream for the same class of bug (dotnet/aspnetcore#65165, dotnet/sdk#48811).
Fixes #20030
Co-authored-by: Bart Koelman <104792814+bart-vmware@users.noreply.github.com>
Constrain port replacers to URL contexts only
Description
Port replacers in template.json were performing global replacements, corrupting numeric values in generated files. For example,
interval: 5000in bootstrap.bundle.js would becomeinterval: 5126when a random port was assigned.Added
onlyIf: [{"after": "localhost:"}]constraint tokestrelHttpPortReplacerandkestrelHttpsPortReplacersymbols:Applied to all web project templates:
Replacement now occurs only in launchSettings.json URLs, preserving all other numeric values.
Original prompt
This pull request was created from Copilot chat.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.