Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blazor has case sensitive URLs when hosted in a Child Directory #6818

Open
RodDaSilva opened this issue Jan 17, 2019 · 36 comments
Open

Blazor has case sensitive URLs when hosted in a Child Directory #6818

RodDaSilva opened this issue Jan 17, 2019 · 36 comments
Labels
area-blazor Includes: Blazor, Razor Components feature-blazor-server feature-routing Pillar: Technical Debt Priority:2 Work that is important, but not critical for the release

Comments

@RodDaSilva
Copy link

(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 ---

@Eilon Eilon added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Jan 18, 2019
westerncj pushed a commit to westerncj/AspNetCore that referenced this issue Jan 31, 2019
@danroth27 danroth27 added the area-blazor Includes: Blazor, Razor Components label Feb 6, 2019
@rynowak rynowak added the bug This issue describes a behavior which is not expected - a bug. label Mar 15, 2019
@rynowak rynowak added this to the 3.0.0-preview6 milestone Mar 15, 2019
@mkArtakMSFT mkArtakMSFT modified the milestones: 3.0.0-preview6, Backlog Apr 19, 2019
@mkArtakMSFT mkArtakMSFT removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels May 9, 2019
@danroth27 danroth27 modified the milestones: Backlog, 3.0.0-preview8 May 24, 2019
@mkArtakMSFT mkArtakMSFT modified the milestones: 3.0.0-preview8, 3.1.0 Jun 25, 2019
@RealTadango
Copy link

RealTadango commented Aug 12, 2019

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>

@ThatRickGuy
Copy link

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/'.

@SteveSandersonMS SteveSandersonMS added affected-few This issue impacts only small number of customers severity-minor This label is used by an internal tool labels Oct 6, 2020 — with ASP.NET Core Issue Ranking
@nikki9696
Copy link

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.

@Otto404
Copy link

Otto404 commented Feb 8, 2021

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/'.

@javiercn
Copy link
Member

javiercn commented Feb 8, 2021

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(....);

@mkArtakMSFT mkArtakMSFT removed the bug This issue describes a behavior which is not expected - a bug. label Feb 8, 2021
@sam-wheat
Copy link

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

@ghost
Copy link

ghost commented Oct 6, 2023

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.

@githubuser6000
Copy link

" 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

@ghost
Copy link

ghost commented Dec 12, 2023

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.

@githubuser6000
Copy link

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.

@mkArtakMSFT
Copy link
Member

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 mkArtakMSFT added the Priority:2 Work that is important, but not critical for the release label Jan 11, 2024
@alwilton
Copy link

Having it as an option would be great.

@SPWizard01
Copy link

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....

@vbonduel
Copy link

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 ;)

@kenasanion-dtkph
Copy link

Hello team,

This is also an issue that keeps getting pushed. We need it also :(
Thanks for the workaround but I hope there's a fix already like an option to be case insensitive

Thanks,
Ken

@ggraitzer
Copy link

My team is experiencing this as well with a couple new websites we are developing using Blazor. We are still a ways out from either being ready to go to production but we are very much hoping this will have a better resolution by then.

@philip-pandoscape
Copy link

  1. It's really sad that Microsoft hasn't addressed this issue yet.

  2. Here is a solution to the problem for those using .NET 8 Server Side Blazor. For WASM, I think you would need to do something in JavaScript, however, I do not have this problem in WASM like I do in Server Side.

Add in a setting to the appsettings.json like so:

{
     "BASE_PATH": "/app"
}

Add in a class that will programmatically set the base path in App.razor.

 public class BlazorQualityControlService
 {
     IConfiguration Configuration;
     IHttpContextAccessor HttpContextAccessor;

     public BlazorQualityControlService(IHttpContextAccessor accessor, IConfiguration configuration)
     {
         HttpContextAccessor = accessor;
         Configuration = configuration;
     }

     public string GetBasePath()
     {
         // If the base path was set, find it in the base URI.
         if (Configuration["BASE_PATH"] != null)
         {
             // Find the part of the request URI that matches the base path using case insensitive matching.
             string basePath = Configuration["BASE_PATH"] ?? "";
             string requestPath = HttpContextAccessor.HttpContext?.Request.GetDisplayUrl() ?? "";
             int index = requestPath.IndexOf(basePath, StringComparison.OrdinalIgnoreCase);

             // Grab the case-sensitive base path from the request URI.
             string qualityControlBasePath = basePath;
             if (index >= 0)
             {
                 qualityControlBasePath = requestPath.Substring(index, basePath.Length);
             }

             return qualityControlBasePath + "/";
         }
         else
         {
             return "/";
         }
     }
 }

Add in the service in your start up:

builder.Services.AddTransient<BlazorQualityControlService>();

Update the App.razor to use the service:

@inject BlazorQualityControlService BlazorQualityControlService

<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <base href="@(BlazorQualityControlService.GetBasePath())" />

Additionally, I also have the following set:

if (builder.Configuration["BASE_PATH"] != null)
{
   app.UsePathBase(builder.Configuration["BASE_PATH"]);
}

FYI, I place this app.UsePathBase after app.UseRouting().

I tested this with both setting a BASE_PATH and not setting a BASE_PATH and it seems to work for me. I hope this helps!

@S-Luiten
Copy link
Contributor

Here's another workaround for those moving from blazor server to blazor web:

public static class NavigationManagerExtensions
{
    public static string GetBasePath(this NavigationManager navigationManager)
    {
        return new Uri(navigationManager.BaseUri).GetComponents(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
    }
}
@inject NavigationManager NavigationManager

<head>
	<base href="@(NavigationManager.GetBasePath())" />
</head>

@Edemilorhea
Copy link

And

  1. It's really sad that Microsoft hasn't addressed this issue yet.
  2. Here is a solution to the problem for those using .NET 8 Server Side Blazor. For WASM, I think you would need to do something in JavaScript, however, I do not have this problem in WASM like I do in Server Side.

Add in a setting to the appsettings.json like so:

{
"BASE_PATH": "/app"
}
Add in a class that will programmatically set the base path in App.razor.

public class BlazorQualityControlService
{
IConfiguration Configuration;
IHttpContextAccessor HttpContextAccessor;

 public BlazorQualityControlService(IHttpContextAccessor accessor, IConfiguration configuration)
 {
     HttpContextAccessor = accessor;
     Configuration = configuration;
 }

 public string GetBasePath()
 {
     // If the base path was set, find it in the base URI.
     if (Configuration["BASE_PATH"] != null)
     {
         // Find the part of the request URI that matches the base path using case insensitive matching.
         string basePath = Configuration["BASE_PATH"] ?? "";
         string requestPath = HttpContextAccessor.HttpContext?.Request.GetDisplayUrl() ?? "";
         int index = requestPath.IndexOf(basePath, StringComparison.OrdinalIgnoreCase);

         // Grab the case-sensitive base path from the request URI.
         string qualityControlBasePath = basePath;
         if (index >= 0)
         {
             qualityControlBasePath = requestPath.Substring(index, basePath.Length);
         }

         return qualityControlBasePath + "/";
     }
     else
     {
         return "/";
     }
 }

}
Add in the service in your start up:

builder.Services.AddTransient();
Update the App.razor to use the service:

@Inject BlazorQualityControlService BlazorQualityControlService

Additionally, I also have the following set:

if (builder.Configuration["BASE_PATH"] != null)
{
app.UsePathBase(builder.Configuration["BASE_PATH"]);
}

FYI, I place this app.UsePathBase after app.UseRouting().

I tested this with both setting a BASE_PATH and not setting a BASE_PATH and it seems to work for me. I hope this helps!

This way is worked on .Net 8

But When I upgrade to .Net 9

Blazor.web.js is break.

Image

it can't relly to use blazor.web.js work

@philip-pandoscape
Copy link

@Edemilorhea I could be wrong, but the error does not seem related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components feature-blazor-server feature-routing Pillar: Technical Debt Priority:2 Work that is important, but not critical for the release
Projects
None yet
Development

No branches or pull requests