Johnny Oshika
Johnny Oshika

Reputation: 57482

ASP.Net Core: Use Shared Project to share static assets (css / js) between many projects

Taking inspiration from here: http://rion.io/2017/03/22/sharing-is-caring-using-shared-projects-in-asp-net/, I'm trying to use Shared Projects to share static assets (e.g. css / js) between multiple ASP.Net Core projects.

I created a shared project and added this file in this folder hierarchy:

enter image description here

I then added a reference to this shared project from my ASP.Net Core web project. However, I'm not able to access this file when I run the project. I tried these URLs (among many others):

http://localhost:50000/assets.style.css
http://localhost:50000/wwwroot/assets/style.css

They all result in 404. It seems like I either haven't found a way to make these files available in my web project or I'm referencing them incorrectly. Anyone know how to make this work?

Upvotes: 9

Views: 3636

Answers (2)

Andres
Andres

Reputation: 2899

I know this question is two years old, but I needed to share static assets in my blazor app that is supporting the two hosting models (Server & WebAssembly) and found another solution.

Just in case, the Shared project is a Razor Class Library.

enter image description here

The wwwroot is on the Ux.Shared project which is referenced by both Ux.Server (Blazor Server Hosting Model) and Ux.Wasm (Blazor WebAssembly Hosting Model). To use this assets in both projects you just use:

_content/{LIBRARY NAME}/

Then for example in the index.html of each project you reference this asset like this:

 <link href="_content/Ux.Shared/css/bootstrap/bootstrap.min.css" rel="stylesheet" />

This works fine in Blazor, I guess its working in Asp .Net Core too.

Upvotes: 9

Johnny Oshika
Johnny Oshika

Reputation: 57482

Here's how I solved this problem. I didn't use a Shared Project because I couldn't get that to work. Instead, I used PhysicalFileProvider and it works like charm.

To do this, I created a new folder in src. I called it assets so my Solution Explorer looks something like this:

src/assets
src/Foo.Web1
src/Foo.Web2
test/Foo.Tests

I put all of the shared static assets (e.g. css, JavaScript, images) in /src/assets. Now I map /src/assets to the wwwroot/assets folders in Foo.Web1 and Foo.Web2 projects using PhysicalFileProvider. In Startup.cs's Configure method, I add this:

if (Env.IsDevelopment())
{
    // app is IApplicationBuilder and Env is IHostingEnvironment
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(Regex.Replace(Env.ContentRootPath, $"{Env.ApplicationName}$", "assets"))),
        RequestPath = new PathString("/assets"),
        OnPrepareResponse = ctx =>
        {
            // Optionally manipulate the response as you'd like. for example, I'm setting a no cache directive here for dev.
            ctx.Context.Response.Headers.Append("Cache-Control", "no-cache, no-store, must-revalidate");
        }
    });
}

Now any request that comes to /assets will be served from the /src/assets folder that can be shared by Foo.Web1 and Foo.Web2. All changes in /src/assets will be reflected in real-time. This work great in dev, but when it comes to production, I don't do this. Instead, I copy the files from /src/assets to Foo.Web1/wwwroot/assets and Foo.Web2/wwwroot/assets in my deployment script so this remapping doesn't need to happen.

Upvotes: 6

Related Questions