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.48k stars 10.04k forks source link

Blazor Server "Error: Invocation canceled due to the underlying connection being closed" when trying to change base path #58981

Open BinaryFly opened 2 hours ago

BinaryFly commented 2 hours ago

Motivation

I have a .NET 8 Blazor server app where I wish to change the base url for. This is because I need to deploy my application to IIS and it will be locally hosted using a reverse proxy. "Why do you need to change the base url for this?" I hear you asking. Well eventually there should be multiple blazor applications that are all locally hosted and served via a reverse proxy on the same machine, and I distinguish these applications using their base path.

i.e. I have the following 2 apps: Name Called upon via Hosted on by IIS Rewrite rule in IIS
CarApp http://localhost/root/car http://localhost:8081 ^root/car(.*) -> http://localhost:8081{R:1}
HouseApp http://localhost/root/house http://localhost:8082 ^root/house(.*) -> http://localhost:8082{R:1}

The thing is that my static files are not served correctly if I don't adjust the base path of my application. Static files would be retrieved via the root of the URL where the first html file loads in, which is localhost without a specified port (and thus will give back an error 404).

Say that for example the following is a snippet of my App.razor for my CarApp.

    <base href="/"/>
    <link rel="stylesheet" href="app.css" />

Now let's say that the user calls http://localhost/root/car, what will happen?

  1. The application will try to retrieve the app.css from http://localhost/app.css
  2. This will give back a 404 since app.css is hosted on http://localhost:8081/app.css not on http://localhost/app.css.

A way to prevent this from happening would be to set another rewrite rule in iis to rewrite http://localhost/app.css (for example) to http://localhost:8081/app.css. But what if we also want to load in our HouseApp, and this has its app.css link specified in the same way? Then we would get back the app.css from our CarApp since it would be rewritten to localhost:8081.

My Solution

To try and circumvent this issue, I tried setting the base path for blazor server as specified in the manual. After setting the base tag in my App.razor the static files can be retrieved from the specified base.

...
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="root/subpath/" />
    <link rel="stylesheet" href="app.css" />
    <link rel="stylesheet" href="BlazorTest.styles.css" />
    <HeadOutlet @rendermode="InteractiveServer" />
</head>
...

Next to this I also set the pathbase using app.UsePathBase because some files will still look for the root of the url instead of taking on the base specified by the base html tag, and app.UsePathBase makes these files also be hosted on the specified path base (an example of such a file would be _framework/blazor.web.js).

Lastly I also used app.MapBlazorHub as was explained in the documentation to make sure my signalr connection uses the right path.

// added the following to my Program.cs
var app = builder.Build();

app.UsePathBase("/mesapp/downtimes");
app.MapBlazorHub("mesapp/downtimes");
app.UseStaticFiles();

Using these steps would make it so static files are being served with the appropriate base path that I specified in these steps. So where we the browser first tried to retrieve app.css via http://localhost/app.css, it will now try to retrieve it via http://localhost/<newpathbase>/app.css.

Issue

When using the steps I wrote above, all the files and requests are correctly retrieved and executed (see screenshot).

Image

But unfortunately, the signalR connection can't be made.

Image

Even when testing this locally and without using IIS or a reverse proxy, I still face the same issue. I also tried to visit the page via /root/subpath, but then I see the following:

Image

At this point I have no idea what I'm doing wrong and how I can fix my issue, I also found many different issues vaguely relating to this, but that are maybe out of date or do not correctly fit my use case.

As an example I also created a test repo that demonstrates this issue.

javiercn commented 1 hour ago

@BinaryFly thanks for contacting us.

If you turn on detailedErrors and turn the logging level all the way to debug what do you see on the server logs?

dotnet-policy-service[bot] commented 1 hour ago

Hi @BinaryFly. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.