aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Blazor has case sensitive URLs when hosted in a Child Directory

Open RodDaSilva opened this issue 6 years ago • 30 comments

(NOTE: this report is in the context of "server-side" Blazor app hosting)

It is possible to host Blazor in a child directory by:

  1. Adding an app.Map() in the Startup.Configure() method of the host:

app.Map("/dashboard", child => { child.UseServerSideBlazor<DiskBounty.Dashboard.Startup>(); });

and

  1. Changing the base href in the index.html of the Blazor App:

    base hef="/dashboard/"

However, if you do this you can only use the casing of the base href to access your Blazor pages. For example /dashboard/counter and /dashboard/Counter will work but /Dashboard/counter will not. That is you must always specify 'dashboard' (in this example) within the URL in lower case. This is a behavior difference to when the Blazor app is hosted in the root directory, where all urls are case insensitive.

The error you get is:

warn: Microsoft.AspNetCore.Blazor.Server.BlazorHub[0] Unhandled Server-Side exception System.AggregateException: One or more errors occurred. (Error: No element is currently associated with component 1) ---> Microsoft.AspNetCore.Blazor.Browser.Rendering.RemoteRendererException: Error: No element is currently associated with component 1 --- End of inner exception stack trace ---

RodDaSilva avatar Jan 17 '19 21:01 RodDaSilva

Temporary fix: Put this in the index.html, above the blazor script tag:

<script>
    var path = window.location.pathname.split('/');
    var baseTag = document.getElementsByTagName('base');
    baseTag[0].setAttribute('href', '/' + path[1] + '/');
</script>

RealTadango avatar Aug 12 '19 11:08 RealTadango

Still seeing this in 3.1 preview client side blazor app. http://ringdev.com/Iosian4 works http://ringdev.com/iosian4 does not, throws blazor.webassembly.js:1 WASM: System.ArgumentException: The URI 'http://ringdev.com/iosian4' is not contained by the base URI 'http://ringdev.com/Iosian4/'.

ThatRickGuy avatar Jan 02 '20 04:01 ThatRickGuy

Same issue for us with a client size WASM hosted using Core. MapFallbackToFile has a path (we have the app in a child directory) and that path has to match including case of the base href in index.html or we get the error Rick mentioned. Please fix - we can't control how others link to our app, only our own links.

nikki9696 avatar Jan 19 '21 16:01 nikki9696

Still see this in Blazor WASM .NET 5, WebAssembly 5.0.2

blazor.webassembly.js:1 System.ArgumentException: The URI 'https://localhost:44302/firstapp' is not contained by the base URI 'https://localhost:44302/FirstApp/'.

Otto404 avatar Feb 08 '21 06:02 Otto404

This is not a bug.

Map is case sensitive, see here

If you want it to be case insensitive you can use Mapwhen instead:

map.MapWhen(c => c.Request.Path.StartsWithSegments("firstapp", StringComparison.OrdinalIgnoreCase),
   child => child.UseServerSideBlazor(....);

javiercn avatar Feb 08 '21 16:02 javiercn

This is not a bug.

Map is case sensitive, see here

If you want it to be case insensitive you can use Mapwhen instead:

map.MapWhen(c => c.Request.Path.StartsWithSegments("firstapp", StringComparison.OrdinalIgnoreCase),
   child => child.UseServerSideBlazor(....);

Seems a little backwards. URLs are usually case insensitive as it's a way better user experience. So why would the default implementation be case sensitive and require a rather verbose lambda to behave the common way? Why not have map work case insensitive and in the rare situation where someone requires case sensitivity, they can use MapWhen?

ThatRickGuy avatar Feb 08 '21 16:02 ThatRickGuy

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

ghost avatar Feb 09 '21 17:02 ghost

Agree with Rick, this is a trip hazard that will keep catching people out. Should reopen and resolve.

MikeADoodleDo avatar Feb 10 '21 10:02 MikeADoodleDo

Seems a little backwards. URLs are usually case insensitive as it's a way better user experience. So why would the default implementation be case sensitive and require a rather verbose lambda to behave the common way?

That's not the case, urls are case sensitive in most hosts, it's asp.net core routing that decides to treat them in a case insensitive way.

I'll reopen this issue and route it to the proper folks to consider the ask here to add a Map overload that provides the desired casing

javiercn avatar Feb 10 '21 10:02 javiercn

We need an API proposal to move this forward. Can somebody propose something?

davidfowl avatar Mar 29 '21 14:03 davidfowl

Question: How do you suggest fixing this in Blazor WebAssembly? I fail to see a solution to this issue, as I have stumbled upon this problem aswell, because Blazor WebAssembly does not have a feature that allows me to set rules for the base url. Neither have I ever had a reason to have case-sensitivity in the first place. Errors like these are ugly, and unnecessary. I suggest keeping it case-insensitive.

RoyvdWijk avatar Apr 08 '21 09:04 RoyvdWijk

ASP.NET routing will respond in a case-insensitive manner. Blazor WASM not responding in the same way is inconsistent. Users generally don't care about case senstivity when typing in a URL; but now with Blazor they will need to (without some kind of "hack"). There needs to be some kind of flag so that Blazor WASM treats the base URI in a case insensitive manner (ideally defaulted to correspond to the hosting environment or the type of project created in Visual Studio).

darcyreimer avatar Apr 19 '21 19:04 darcyreimer

I just ran into this on .NET 6.0.2 application and I'm quite surprised at this. It goes directly against any expected URL behavior which is case-insensitive. How do I explain to the multitude of users that this is different and is case-sensitive against convention? The helpdesk will not be pleased.

alwilton avatar Mar 05 '22 15:03 alwilton

Same issue here. Would like a solution.

viewsh avatar Mar 16 '22 15:03 viewsh

How do I, for blazor wasm, use case insensitive URLs?

githubuser6000 avatar Aug 16 '22 06:08 githubuser6000

just stumbled upon this issue as well. Shouldn't it be enough to change the comparison to OrdinalIgnoreCase?

https://github.com/dotnet/aspnetcore/blob/39f0e0b8f40b4754418f81aef0de58a9204a1fe5/src/Components/Components/src/NavigationManager.cs#L226-L246

A workaround is to reload the application to the base path with the correct casing in index.html.

<head>
    <base href="/" />
    <script type="text/javascript">
        if (!location.href.startsWith(document.baseURI)) {
            // force a reload to the correct, case-sensitive URL
            location.href = document.baseURI + location.href.substring(document.baseURI.length);
        }
    </script>
</head>

marcOcram avatar Oct 24 '22 08:10 marcOcram

@javiercn, Map isn't case sensitive. https://github.com/dotnet/aspnetcore/blob/d5629a0534ced8534226e321bfefff475160963e/src/Http/Http.Abstractions/src/Extensions/MapExtensions.cs#L35 https://github.com/dotnet/aspnetcore/blob/d5629a0534ced8534226e321bfefff475160963e/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs#L54 https://github.com/dotnet/aspnetcore/blob/d5629a0534ced8534226e321bfefff475160963e/src/Http/Http.Abstractions/src/PathString.cs#L280-L282

The error reported above is coming from somewhere else. blazor.webassembly.js:1 WASM: System.ArgumentException: The URI 'http://ringdev.com/iosian4' is not contained by the base URI 'http://ringdev.com/Iosian4/'.

Tratcher avatar Oct 27 '22 20:10 Tratcher

map.MapWhen(c => c.Request.Path.StartsWithSegments("firstapp", StringComparison.OrdinalIgnoreCase),
   child => child.UseServerSideBlazor(....);

If this works then it's not because of the casing. The biggest difference between Map and MapWhen is that Map trims the matched segment off of Path and appends it to PathBase. This change could be causing the path not to match something later in the pipeline. Map now has a preserveMatchedPathSegment that can be set to true to prevent modifying the path. See if that helps. https://github.com/dotnet/aspnetcore/blob/d5629a0534ced8534226e321bfefff475160963e/src/Http/Http.Abstractions/src/Extensions/MapExtensions.cs#L49

Tratcher avatar Oct 27 '22 20:10 Tratcher

Thanks for contacting us.

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

ghost avatar Oct 31 '22 16:10 ghost

@javiercn Since this is assigned to you, here's what we just discussed in a meeting:

  • In general Blazor has to walk a line between following ASP.NET Core conventions and following browser conventions. In this case, with URL case-sensitivity, the conventions disagree so whatever we do, somebody's going to be unhappy
  • Two possible workarounds for people who really want case-insensitivity:
    • The client-side solution given at https://github.com/dotnet/aspnetcore/issues/6818#issuecomment-520395577
    • A server-side solution: adding middleware to do a 301 redirect from /SomeSubDiR to /somesubdir so that you always have canonical URLs. TBH this feels like the right-est solution as having a canonical form for URLs is desirable for SEO etc.

The idea of baking in some kind of case-insensitivity to client-side URL handling feels pretty disturbing but theoretically I recognize it could be an option, so that heretics could enable it at their own peril 😄

SteveSandersonMS avatar Oct 31 '22 16:10 SteveSandersonMS

I suppose one could argue that we already have some scenarios in client-side URL handling where it's case-insensitive, such as Blazor's routing system itself, which is derived from ASP.NET Core's server-side routing.

SteveSandersonMS avatar Oct 31 '22 16:10 SteveSandersonMS

Just ran into this issue in production. My client is a large company. I sold them on using Blazor.
Now I'm embarrassed to have to write this to my manager:

image

sam-wheat avatar Sep 11 '23 17:09 sam-wheat

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.

ghost avatar Oct 06 '23 17:10 ghost

" or it's very rare and low-impact issue, we will close it " I am slightly disappointed, and I get triage has to happen, but this issue just makes blazor a nonstarter due to this. Might impact SEO etc if users aren't aware. So that just leads to this feedback loop -> issue -> no one uses -> no interest -> no fix -> issue

Oh well

githubuser6000 avatar Oct 28 '23 06:10 githubuser6000

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.

ghost avatar Dec 12 '23 18:12 ghost

We should celebrate the 4 year anniversary of this arguably breaking bug in a ~ a month! 🥳

I sympathize with Sam, I almost sold people on Blazor.

githubuser6000 avatar Dec 13 '23 12:12 githubuser6000

Had a quick discussion with the team about this one and we will consider adding an option to opt-in into the desired behavior (keeping the current behavior as default).

mkArtakMSFT avatar Jan 11 '24 17:01 mkArtakMSFT

Having it as an option would be great.

alwilton avatar Jan 11 '24 18:01 alwilton

this is quite high impact for us, because having a lot of people within the company everyone types urls differently, this is especially bad when people type in the url incorrectly the first time, browser caches it in history, and it will never work for the user unless he goes through other URL or clears browser history....

SPWizard01 avatar Jan 28 '24 10:01 SPWizard01

Hi team. I fully agree with people here. What if a reference to the Web site is made with a bad casing => The link will be broken. It is not possible to control how the URL will be written. So the best would be to make it not case sensitive. Or at least to have it as an option. thx ;)

vbonduel avatar Mar 13 '24 18:03 vbonduel