MapStaticAssets serves 0 bytes for fingerprinted URLs of files included via <Content Include + Link> from external paths
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
Briefly searched — could not find an exact match. Apologies if duplicate.
### Describe the bug
When a static asset is added to a Web project via `` (i.e. linked from an external folder outside the project tree), `MapStaticAssets()` registers a fingerprinted route in the static-web-assets endpoints manifest but the actual HTTP response is **HTTP 200 with `Content-Length: 0`**.
The unfingerprinted route (`/css/file.css`) is served correctly with the real content via `UseStaticFiles()`. Files that physically live inside the project's own `wwwroot/` directory are unaffected — their fingerprinted URLs work.
The build is up-to-date: source, the copy in `bin/.../wwwroot/css/`, and the precompressed `.gz` variant all contain the correct bytes.
### Expected Behavior
The fingerprinted URL produced by `MapStaticAssets()` should serve the same bytes as the source (and the unfingerprinted URL), regardless of whether the file lives literally inside `wwwroot/` or is brought in via `` from an external path.
### Steps To Reproduce
1. Create a Razor Pages web project `WebsiteMain` targeting `net10.0`.
2. Add a sibling folder `WebsiteShared/css/` with a single file `website-shared-colors.css` containing e.g. `:root { --primary: #0d6efd; }`.
3. In `WebsiteMain.csproj`:
```xml
```
4. In `Program.cs`:
```csharp
app.UseStaticFiles();
app.MapStaticAssets();
app.MapRazorPages().WithStaticAssets();
```
5. In `_Layout.cshtml`:
```html
```
6. Build and run. The rendered URL is fingerprinted, e.g. `/css/website-shared-colors.oz0lyd3jv2.css`.
7. `curl -s -o /dev/null -w "%{size_download}" http://localhost:5117/css/website-shared-colors.oz0lyd3jv2.css` → **0**.
8. `curl -s -o /dev/null -w "%{size_download}" http://localhost:5117/css/website-shared-colors.css` → 3092 (correct).
9. The endpoints manifest (`obj/.../staticwebassets.build.endpoints.json`) declares `Content-Length: 3092` for the fingerprinted route, inconsistent with the actual response.
Workaround: remove `MapStaticAssets()` and `.WithStaticAssets()` and rely on `asp-append-version` query-string cache-busting. Plain `UseStaticFiles()` handles both literal-wwwroot and linked-content files correctly.
### Exceptions (if any)
None. Request returns 200 with an empty body.
### .NET Version
10.0.105 (target framework `net10.0`)
### Anything else?
Manifest excerpt for the affected route (extracted from `staticwebassets.build.endpoints.json`):
```json
{
"Route": "css/website-shared-colors.oz0lyd3jv2.css",
"AssetFile": "css/website-shared-colors.css",
"Selectors": [],
"ResponseHeaders": [
{ "Name": "Cache-Control", "Value": "max-age=31536000, immutable" },
{ "Name": "Content-Length", "Value": "3092" },
{ "Name": "Content-Type", "Value": "text/css" }
]
}
```
`AssetFile` is a relative path (`css/website-shared-colors.css`) without an explicit content-root prefix. For linked content from an external project the build pipeline copies the file into `bin/.../wwwroot/css/`, but the static-asset endpoint apparently cannot resolve the bytes back at request time.
Contributor guide
Assessment
This issue has not been assessed yet.