If you pass any kind of StaticFileOptions
object to app.UseStaticFiles()
, then Blazor Server will no longer be able to serve blazor.server.js
, breaking Blazor.
app.UseStaticFiles()
call in Startup.Configure to read app.UseStaticFiles(new StaticFileOptions())
What appears to be happening is that if you don't pass any configuration to UseStaticFiles
, then the framework correctly calls ConfigureStaticFilesOptions.PostConfigure
after the pipeline is built. This configures the static file middleware to serve the Blazor JS from manifest resources.
As soon as there's any configuration passed to UseStaticFiles
, then ConfigureStaticFilesOptions
is no longer called. It doesn't matter what specific properties are in the StaticFileOptions
object - it's just the presence of the object which causes the problem.
I will debug this further if it's helpful, but I suspect someone more familiar with the IPostConfigureOptions
mechanism will know what's going on instantly.
Maybe there's some work-around, but if so then it would be helpful if it could be somehow more obvious, because "I added a static file extension and Blazor stopped working" is somewhat surprising.
I think this may be same issue as #18222, which was perhaps rather confusingly titled and ended up being closed, but I think there is a real issue here.
Does it work if you add a second instance of UseStaticFiles with options rather than modifying the existing one?
@Tratcher It does!
I am not sure where I currently am on the amazed <-> appalled spectrum...
:grin: UseStaticFiles is designed to support multiple instances if you pass in the options directly. UseStaticFiles() with no parameters pulls the options from DI which is likely where Blazor is tweaking the settings.
@Tratcher Thanks - that does make sense, though I didn't expect it at all, and it feels like a bit of a gotcha.
Would it perhaps be possible for Blazor to detect that it has never been given the chance to run its static file config code and explode somehow early in the run?
That would also catch the case where you didn't have a UseStaticFiles
at all - I have seen other people on-line struggling with that.
Or, rather than co-opting (hijacking) the UseStaticFiles to serve-up the manifest resources, could there just be a separate bit of middleware: UseBlazorStaticResources
or something, which just served the specific Blazor bits and didn't touch the normal StaticFile middleware?
Yeah, blazor should be adding their own static file handler like UseBlazorStaticResources rather than messing with the default.
We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.
I just tried adding another call to app.UseStaticFiles()
and it now works! That is blazor.server.js
is served, as is my site.webmanifest
file. To be clear this is what I now have in Startup.Configure(...)
:
app.UseStaticFiles();
FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();
provider.Mappings[".webmanifest"] = "application/manifest+json";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider
});
Not keen on this, but at least it works!
I've just ran in to this which is very confusing behaviour.
I can confirm that @benm-eras workaround is working as expected.
I've encountered the same problem.
The solution also comes in this other message which proposes two alternatives:
https://github.com/dotnet/aspnetcore/issues/9588#issuecomment-505465169
The first is the ideal solution. The second is a hack that I would not recommend.
Example:
// ConfigureServices method
services.Configure<StaticFileOptions>(options => {
FileExtensionContentTypeProvider contentTypeProvider = new FileExtensionContentTypeProvider();
contentTypeProvider.Mappings[".gpx"] = "application/gpx+xml";
options.ContentTypeProvider = contentTypeProvider;
});
// Configure method
app.UseStaticFiles();
Most helpful comment
Yeah, blazor should be adding their own static file handler like UseBlazorStaticResources rather than messing with the default.