aspnetcore: Passing options to UseStaticFiles breaks Blazor Server's static file service
Describe the bug
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.
To Reproduce
- Create the template Blazor Server app
- Run it and observe that it works correctly
- Change the
app.UseStaticFiles()call in Startup.Configure to readapp.UseStaticFiles(new StaticFileOptions()) - Run the app again and observe that blazor.server.js is 404’d, and hence the app doesn’t work.
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.
Further technical details
- ASP.NET Core version 3.1.2
- The IDE (VS / VS Code/ VS4Mac) you’re running on, and it’s version VS 16.4.5 on Win10
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 6
- Comments: 17 (6 by maintainers)
Yeah, blazor should be adding their own static file handler like UseBlazorStaticResources rather than messing with the default.
I just tried adding another call to
app.UseStaticFiles()and it now works! That isblazor.server.jsis served, as is mysite.webmanifestfile. To be clear this is what I now have inStartup.Configure(...):Not keen on this, but at least it works!
What a phenomenal time-sink this bug turned out to be for me. Glad there is a suggested workaround, but definitely wish this had been more obvious from the beginning.
Note that this issue can be resolved by using the options pattern in ConfigureServices:
and then call UseStaticFiles() in the standard way (without any parameters) in Configure.
You guys should fix this, because it’s a ridiculous bug and Blazor should never have broken the defaults like it did. As @Tratcher observed two and a half years ago.
In terms of trying to encourage people to adopt MS tech, I think fixing these sort of festering sores of massive wasted-time for professional developers would give you far more bang-for-buck than all the “write a web app in one line of code” stuff which seems to get so much effort.
I agree with Will. More effort has gone into punting this over and over than there would have been exhausted in just fixing it. You make a mess, you clean it up. Why is this so hard to understand?
On Tue, Sep 20, 2022 at 2:22 AM Will Dean @.***> wrote:
Thanks for contacting us.
We’re moving this issue to the
.NET 8 Planningmilestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it’s very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.I’ve ran into this issue today when I was trying to set the response HTTP headers for static files (.css, .js) that I’m serving as part of my Blazor website.
I’ve followed the documentation https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-6.0#set-http-response-headers but it took me a couple of hours before I realized what the issue was and stumbled upon this bug report.
Adding multiple calls to
UseStaticFiles()fixed the issue, but interestingly it seems that the order in which they occur matters. I had to place my overrides before the empty call, or the error would still pop up.I just wanted to add static asset caching and stumbled upon this problem.
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:
@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
UseStaticFilesat 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:
UseBlazorStaticResourcesor something, which just served the specific Blazor bits and didn’t touch the normal StaticFile middleware?@Tratcher It does!
I am not sure where I currently am on the amazed <-> appalled spectrum…