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 static assets - conflicting assets with the same path #20580

Closed
dazinator opened this issue Apr 6, 2020 · 2 comments
Closed

Blazor static assets - conflicting assets with the same path #20580

dazinator opened this issue Apr 6, 2020 · 2 comments
Assignees
Labels
area-blazor Includes: Blazor, Razor Components question
Milestone

Comments

@dazinator
Copy link

dazinator commented Apr 6, 2020

Scenario is to do with hosting two (multiple) different blazor wasm client applications, from a single .net core host project, and serving the correct one up on the root "/" url.

Prior to Blazor 3.2 preview 2, a single host could chose to serve up different front end client wasm projects on the root path, based on some logic like this:

if(isTenantA)
{
     app.UseClientSideBlazorFiles<ClientA.Program>() 
    /// stuff 
    endpoints.MapFallbackToClientSideBlazor<ClientA.Program>("index.html") 
    
}
else
{
     app.UseClientSideBlazorFiles<ClientB.Program>() 
    /// stuff 
    endpoints.MapFallbackToClientSideBlazor<ClientB.Program>("index.html") 
}

In this scenario, there are two blazor client wasm projects, and the host can serve up the correct one based on a decision it makes such as who is the current tenant. This sets up a FileProvider pointing to the correct wasm's static content location. The client wasm projects can all have files named "image1.png" but there are no conflicts - no issues.

After the upgrade to blazor 3.2 preview 2 and the switch to using static assets - it looks like it will have to become something like this:

appBuilder.UseBlazorFrameworkFiles(); // blazor framework files can be served up from root url path

if(isTenantA)
{
 // we want to serve up "ClientA" spa on the root path "/"
 IFileProvider fp = GetStaticFileProviderFor<ClientA.Program>();              
endpoints.MapFallbackToFile("index.html", new StaticFileOptions()
{
     FileProvider = fp
});           
}
else
{
// we want to serve up "ClientB" spa on the root path "/"
IFileProvider fp = GetStaticFileProviderFor<ClientB.Program>();              
endpoints.MapFallbackToFile("index.html", new StaticFileOptions()
{
     FileProvider = fp
});           
}

Where GetStaticFileProviderFor<TProgramType>(); is a method I'll have to write myself that builds a FileProvider that only resolves the particular SPA's static content, but on the root "/" request path.

However the first issue is that the client SPA projects that are referenced from the host (via a project reference) now cause a build error as they each have a file with the same name in their wwwroot directories - so I now get this build error that I didn't see previoulsy:

Severity	Code	Description	Project	File	Line	Suppression State
Error		Conflicting assets with the same path '/images/FOO_Black_Green_Logo_RGB.svg' for content root paths 'C:\Users\DarrellTunnell\source\repos\FOO\src\FOO.Landing.Page\wwwroot\images\FOO_Black_Green_Logo_RGB.svg' and 'C:\Users\DarrellTunnell\source\repos\FOO\src\FOO.Client\wwwroot\Images\FOO_Black_Green_Logo_RGB.svg'.	FOO.Server	C:\Program Files\dotnet\sdk\3.1.102\Sdks\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Microsoft.NET.Sdk.Razor.StaticWebAssets.targets	191	

After doing some more research, I found that I can potentially resolve this error by setting <StaticWebAssetBasePath> in each client SPA project to be something unique.

However suppose I do set that for each wasm:


<StaticWebAssetBasePath>clientA</StaticWebAssetBasePath>


<StaticWebAssetBasePath>clientB</StaticWebAssetBasePath>

I still have to implement the aforementioned GetStaticFileProviderFor<TProgramType>(); method to set up an IFileProvider that will serve from the correct static assets location (ClientA vs ClientB) but serve that content up on the root path "/". I also need to make sure that I am serving the tenant up the SPA ClientA - then they should not be able to request files for /ClientB SPA. I know that Environment.WebRootFileProvider will be configured by default to be able to resolve both SPA's static assets on their Static Assets base paths: "/ClientA" and "/ClientB" respectively and I need to prevent that from happening.

I am pretty sure the key to this lies in building an IFileProvider to serve static assets based on the "StaticWebAssetBasePath" that I provide, but serve those files up on a different path i.e "/". In addition to this concern is working out how to replace or prevent the Environment.WebRootFileProvider from serving up Static Assets on their "StaticWebAssetBasePath"'s by default, so I can instead use the above IFileProvider via some additiopnal static files middleware to be explicit about the SPA i can serve up.

Any guidance on the resolution of this issue that did not exist in preview 1 would be greatly appreciated. Thanks

@dazinator
Copy link
Author

I'm now thinking of this idea #20605

Set each clients StaticWebAssetBasePath to a path that should be hidden by the FileProvider by prefixing the path with a "."

<StaticWebAssetBasePath>.clientA</StaticWebAssetBasePath>
<StaticWebAssetBasePath>.clientB</StaticWebAssetBasePath>

This should result in the SPA static files being hidden by default, then I can add my own IFileProvider to the WebRootFileProvider that will serve up the correct SPA static files based on the tenant (I'll create a PhysicalFileProvider pointing to the "wwwroot/.clientA" and another for "wwwroot/.clientB" and wrap them in a custom IFileProvider that defers to the correct one of those depending on the current tenant.

This will work after a dotnet publish, but in development mode, i'll need #20605 to be fixed for the proper behaviour to work at development time too - i.e those static paths should not be served up by default.

@dazinator
Copy link
Author

dazinator commented Apr 8, 2020

I'll close this - setting <StaticWebAssetBasePath> in each project to a unique path resolves the immediate build issue with conflictint static asset paths. However that leads to #20605

@ghost ghost locked as resolved and limited conversation to collaborators May 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components question
Projects
None yet
Development

No branches or pull requests

4 participants