dotnet / dotnet/aspnetcore

MapStaticAssets serves 0 bytes for fingerprinted URLs of files included via <Content Include + Link> from external paths

Open
#66,833 2 comments 0 reactions 0 assignees View on GitHub
area-middleware feature-static-web-assets
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.