Base solution for your next web application
Open Closed

All In One Solution deyployment issue: Merged ASP.NET Zero (ASP.NET Core + Angular) on Azure Linux App Service: Root routes to backend, Angular login button does nothing / SPA routing mismatch #12592


User avatar
0
pliaspzero created

V13.4 Angular & ASPNET CORE I followed this instrucktion: https://docs.aspnetzero.com/aspnet-core-angular/latest/Deployment-Angular

Hi ASP.NET Zero Support Team,

we are migrating an existing ASP.NET Zero application (ASP.NET Core + Angular, merged solution / “all-in-one”) from Azure Windows App Service to Azure Linux App Service (Code) using .NET 8 runtime.

The application starts successfully and the backend is reachable, but the Angular SPA behaves incorrectly:

Navigating to https://01.pliwfm.one shows the backend (not the Angular UI).

We must explicitly open https://01.pliwfm.one/login to reach the Angular UI.

On the Angular login page, clicking the login button does nothing (no redirect / no API call).

In the UI we also see a “Continue with Google” button even though Google auth is disabled in our config.

This setup works on Windows App Service.

What we did (based on ASP.NET Zero docs)

We followed the merged Angular deployment instructions:

dotnet publish -c Release on the *.Web.Host project

After publish, moved all files from: wwwroot/dist → wwwroot (so Angular index.html is directly in /wwwroot)

We also update both:

Angular settings: assets/appconfig.production.json

Backend settings: appsettings.Production.json

Environment

Hosting: Azure App Service (Linux, Code)

Runtime: .NET 8 (Oryx startup)

Startup command: dotnet WFMOne.Web.Host.dll

Angular is served from: /home/site/wwwroot (merged deployment)

Current behavior / suspected issue

It looks like the SPA fallback/routing is not working as expected on Linux, so:

/ does not resolve to index.html

some auth/login related requests might be returning index.html or being swallowed

possibly reCAPTCHA v3 token generation/validation fails silently

In our Startup.cs we currently have a SPA fallback middleware like:

app.Use(async (context, next) => { await next(); if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value)) { context.Request.Path = "/index.html"; await next(); } }); app.UseStaticFiles();

(We can provide full Startup.cs if needed.)

Questions

In merged mode, should / always resolve to Angular index.html out of the box, even on Linux App Service?

Are there known differences on Linux regarding:

static file hosting order (UseStaticFiles, fallback middleware order)

default documents (index.html)

routing that could cause / to go to backend controllers instead of SPA?

Is there an ASP.NET Zero recommended configuration for hosting merged Angular + API on Linux App Service (Code), especially to ensure SPA fallback works and auth flows are not intercepted?

The “login button does nothing”: are there known cases where reCAPTCHA or dynamic JS bundle loading fails because of wrong paths (e.g. bundling step npm run create-bundles, missing assets, wrong base href)?

What is the exact recommended folder structure after publish on Linux (should Angular end up in /wwwroot root, or /wwwroot/dist, or /wwwroot/wwwroot depending on template)?

Logs / evidence

App starts successfully; container logs show startup command executed and runtime is running. We can provide:

Browser DevTools network log (requests around login click)

screenshot / HAR file

current published folder tree

Thanks in advance — we want to keep both deployment options (merged and separated), but first we need the merged Linux setup to behave exactly like Windows.

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

1 Answer(s)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @pliaspzero

    This issue is not specific to ASP.NET Zero itself, but to differences between Windows App Service (IIS) and Linux App Service (Kestrel/Oryx) when hosting a merged Angular + ASP.NET Core application.

    On Windows, IIS automatically serves index.html as a default document. On Linux App Service, there is no default document behavior, so / is handled by ASP.NET Core routing unless a proper SPA fallback is configured.

    In our case, the root cause was:

    1. SPA fallback middleware order

      • UseStaticFiles() must run before the SPA fallback
      • SPA fallback must be the last middleware
    2. Angular files must be published directly under /wwwroot

      • index.html must be located at /wwwroot/index.html
      • Not under /wwwroot/dist or nested folders
    3. Correct fallback implementation

    app.UseStaticFiles();
    
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
    
    app.Use(async (context, next) =>
    {
        await next();
    
        if (context.Response.StatusCode == 404 &&
            !Path.HasExtension(context.Request.Path.Value) &&
            !context.Request.Path.StartsWithSegments("/api"))
        {
            context.Response.StatusCode = 200;
            context.Request.Path = "/index.html";
            await next();
        }
    });
    
    

    After correcting the middleware order and ensuring Angular is deployed to the /wwwroot root directory, the following issues are resolved:

    • / correctly loads Angular UI
    • Login button works again
    • OAuth / reCAPTCHA behaves correctly
    • UI configuration matches backend config

    This setup now behaves exactly the same way as the Windows Application Service.

    Related Document

    If this solution does not fully resolve the issue, we would be happy to assist further.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)