dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.23k stars 9.95k forks source link

POST operation in Production environment: System.InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' #34420

Closed Alin764 closed 7 months ago

Alin764 commented 3 years ago

Describe the bug

I have a simple ASP Net core 5 application with Angular ( the template was generated with Microsoft Visual Studio Professional 2019 Version 16.8.3 )

In the development environment if I try to do a POST operation to a wrong path I'm getting 404, but in production I'm getting 500 with the exception System.InvalidOperationException: The SPA default page middleware could not return the default page '/index.html'

This behavior is bothering me because I would prefer 404 instead 500. My application is hosted in Azure and from time to time I see many requests like: POST /Index.html, OPTIONS /index.html, DEBUG /index.html.. and many other weird request methods. I don't know the source of these request, seems to be an automated tool, but this is generating a lot of logs with 500 code.

My temporary solution is to put a custom middleware just before app.UseSpa(..), but I believe this is a bug in ASP Net core, and the correct behavior is to return 404, as it is working in development environment. Appreciate if you can give me some advise on my implementation that tries to avoid this error.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ......
    app.Use(async (context, next) =>
    {
        //Redirect to root request to /index.html ( except the GET request ) 
        //Do not generate logs for requests originating from automated tools: POST /Index.html, OPTIONS /index.html, DEBUG /index.htm, etc.. 
        if (!HttpMethods.IsGet(context.Request?.Method)
            && context.Request?.Path.Value.ToLower() == "/index.html")
        {
            context.Response.Redirect("/");
            return;
        }

        try
        {
            await next();
        }
        catch (InvalidOperationException spaException)
        {
            if (spaException.Message.StartsWith("The SPA default page middleware could not return the default page"))
            {
                context.Response.StatusCode = StatusCodes.Status404NotFound;
                return;
            }
            throw;
        }
    });

    app.UseSpa(...);
    .....
}

To Reproduce

  1. Create a new ASP Net core 5 application with Angular in Visual Studio
  2. Run the application ( debug or release mode )
  3. Make a post request with postman to https://localhost:port/WrongPath - this will return 404
  4. Stop the application, switch to release mode and publish the application with folder profile. Keep the default settings - in my case the folder was "MyAppName\bin\Release\net5.0\publish". This action will build the angular frontend also in MyAppName\ClientApp\dist,
  5. In solution explorer, go to project properties, then go to Debug section - environment variables, and change environment from Development to Production
  6. Start the application and make the same post request to https://localhost:port/WrongPath - this time you will get 500 error. Note that this is not a problem with the angular build, navigating to existing path is working fine.

Exceptions (if any)

System.InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' because it was not found, and no other middleware handled the request. Your application is running in Production mode, so make sure it has been published, or that you have built your SPA manually. Alternatively you may wish to switch to the Development environment.

at Microsoft.AspNetCore.SpaServices.SpaDefaultPageMiddleware.<>cDisplayClass0_0.b1(HttpContext context, Func`1 next) at Microsoft.AspNetCore.Builder.UseExtensions.<>cDisplayClass0_1.b1(HttpContext context) at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Builder.UseExtensions.<>cDisplayClass0_2.b2() at Microsoft.AspNetCore.SpaServices.SpaDefaultPageMiddleware.<>cDisplayClass0_0.b0(HttpContext context, Func1 next) at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_1.<Use>b__1(HttpContext context) at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.HttpsPolicy.HstsMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context) --- End of stack trace from previous location --- at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi) at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT1.ProcessRequestAsync() The thread 0x7a20 has exited with code 0 (0x0).

Further technical details

.NET SDK (reflecting any global.json): Version: 5.0.101 Commit: d05174dc5a

Runtime Environment: OS Name: Windows OS Version: 10.0.19042 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.101\

Host (useful for support): Version: 5.0.1 Commit: b02e13abab

.NET SDKs installed: 3.0.101 [C:\Program Files\dotnet\sdk] 3.1.100 [C:\Program Files\dotnet\sdk] 5.0.101 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.All 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

javiercn commented 2 years ago

@James764 thanks for contacting us.

We've significantly changed our approach to developing SPAs in .NET 6.0 and as a result we no longer make use of the SpaProxyMiddleware in our templates. The changes can be ported to earlier versions of the SPA templates, so we suggest you update your app to copy the SPA files to the approach used in 6.0

ghost commented 2 years ago

Thanks for contacting us.

We're moving this issue to the .NET 7 Planning milestone 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.

AnthonyMastrean commented 2 years ago

This issue frequently occurs when running any of the popular web site/application vulnerability scanners (confirmed with Arachni and Nessus).

@javiercn are you saying this shouldn't occur on the new SPA proxy stuff in .NET 6.0? (we haven't migrated yet, so I can't confirm)

awdorrin commented 1 year ago

I ran into this yesterday with an App we were adjusting from the new .Net Core/Angular templates in VS2022 to the older non SPA Proxy approach used in .Net Core 3/Angular. Turns out the angular.json was generating its files in ClientApp/dist while the .csproj file was expecting wwwroot.

In .csproj file, I changed this: <RelativePath>wwwroot\%(RecursiveDir)%(FileName)%(Extension)</RelativePath> to this: <RelativePath>%(DistFiles.Identity)</RelativePath>

This is because our angular.json has, outputPath: dist

     "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "progress": false,
           "outputPath": "dist",
            "index": "src/index.html",
ghost commented 11 months ago

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone 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.

kmjungersen commented 8 months ago

I'm running into this issue with an Angular 15 SPA served from a .NET 7 API. I'm having a difficult time reproducing the issue, but see this error in the API logs.

Commenting to indicate this still appears to be a relevant issue.

javiercn commented 7 months ago

@kmjungersen please file a separate ticket through the Visual Studio report a problem dialog.

The issue you are describing is unrelated to the original issue described here.

javiercn commented 7 months ago

This issue is related to the SpaExtensions package, we recommend migrating to use SpaProxy for development and UseStaticFiles directly as the new templates do.