FallbackSpaProxyingMiddleware 1.0.1

dotnet add package FallbackSpaProxyingMiddleware --version 1.0.1
NuGet\Install-Package FallbackSpaProxyingMiddleware -Version 1.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FallbackSpaProxyingMiddleware" Version="1.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FallbackSpaProxyingMiddleware --version 1.0.1
#r "nuget: FallbackSpaProxyingMiddleware, 1.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install FallbackSpaProxyingMiddleware as a Cake Addin
#addin nuget:?package=FallbackSpaProxyingMiddleware&version=1.0.1

// Install FallbackSpaProxyingMiddleware as a Cake Tool
#tool nuget:?package=FallbackSpaProxyingMiddleware&version=1.0.1

Fallback SPA proxying middleware

This proxy is only intended for use in development, to support HMR and the other features that frontend SPA frameworks support with their built-in web servers. It must not be used in production.

The default SpaServices Microsoft.AspNetCore.SpaProxy is broken and the development-mode SPA proxy tramples all over any defined MVC-style endpoints, directing all requests to the SPA development server, even those you might like to be served by an API controller.

Microsoft claim that this is intentional and that it should be up to the SPA to determine which endpoints to proxy back to the backend. This behaviour is illogical, poorly-documented and differs completely between development and production (where we use UseSpaStaticFiles / endpoints.MapFallbackToFile).

Microsoft will not discuss or even properly document this logic and have locked numerous issues on the matter:

This middleware plays nicely with other MVC endpoints and allows them to serve requests first where a route has been defined. It can be added as follows:

In Program.cs:

// ....
app.UseRouting();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.UseSpa(s =>
{
    if (app.Environment.IsDevelopment())
    {
        s.ApplicationBuilder.UseFallbackSpaProxying("http://localhost:9999");
    }
    // .....
});

The implementation is a bit janky, relying on reflection because the classes we need are marked internal, but it works.

FAQ

You should be using the NPM http-proxy-middleware package and running it under Node.js, not doing this!

No. The server is Kestrel. That's what we are using to do the proxying. The frontend is not in charge here.

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.1 207 5/1/2024
1.0.0 8,832 1/5/2023

Move to using single, re-used HttpClient for proxying