Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Razor Class Library pack static files (js, css etc) too?

Maybe duplicate of this already, but since that post does not have any answer, I am posting this question.

The new Razor Class Library is awesome, but it cannot pack libraries files (like jQuery, shared CSS).

Can I somehow reuse the CSS across multiple Razor Page projects, either using Razor Class Library or anything else (my purpose is that, multiple websites use the same CSS, and a single change applies to all projects).

I have tried creating the folder wwwroot in the Razor Class Library project, but it does not work as expected (I can understand why it should not work).

like image 285
Luke Vo Avatar asked Jul 31 '18 09:07

Luke Vo


People also ask

What is the use of razor class library?

Razor Class Library provides a way to package and distribute UI components to be referenced and reused within a host application. As this doc mentioned , Razor views, pages, controllers, page models, Razor components, View components, and data models can be built into a Razor class library (RCL).

What is static file in C#?

Static files are stored within the project's web root directory. The default directory is {content root}/wwwroot , but it can be changed with the UseWebRoot method. For more information, see Content root and Web root. The CreateDefaultBuilder method sets the content root to the current directory: C# Copy.

What are static files in asp net core?

ASP.NET MVC 5 for Beginners Static files like JavaScript files, images, CSS files that we have on the file system are the assets that ASP.NET Core application can serve directly to clients. Static files are typically located in the web root (wwwroot) folder.


2 Answers

Ehsan answer was correct at the time of asking (for .NET Core 2.2), for .NET Core 3.0, RCL can include static assets without much effort:

To include companion assets as part of an RCL, create a wwwroot folder in the class library and include any required files in that folder.

When packing an RCL, all companion assets in the wwwroot folder are automatically included in the package.

The files included in the wwwroot folder of the RCL are exposed to the consuming app under the prefix _content/{LIBRARY NAME}/. For example, a library named Razor.Class.Lib results in a path to static content at _content/Razor.Class.Lib/.

like image 85
Luke Vo Avatar answered Sep 24 '22 08:09

Luke Vo


You need to embed your static assets into your Razor Class Library assembly. I think the best way to get how to do it is to take a look at ASP.NET Identity UI source codes.

You should take the following 4 steps to embed your assets and serve them.

  1. Edit the csproj file of your Razor Class Library and add the following lines.

     <PropertyGroup>   ....        <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>   ....  </PropertyGroup>   <ItemGroup>      ....      <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.2" />      <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />      <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.1" />      <PackageReference Include="Microsoft.NET.Sdk.Razor" Version="$(MicrosoftNETSdkRazorPackageVersion)" PrivateAssets="All" />     .....  </ItemGroup>  <ItemGroup>     <EmbeddedResource Include="wwwroot\**\*" />     <Content Update="**\*.cshtml" Pack="false" /> </ItemGroup> 
  2. In your Razor Class Library, create the following class to serve and route the assets. (it assumes your assets are located at wwwroot folder)

    public class UIConfigureOptions : IPostConfigureOptions<StaticFileOptions> {     public UIConfigureOptions(IHostingEnvironment environment)     {         Environment = environment;     }     public IHostingEnvironment Environment { get; }      public void PostConfigure(string name, StaticFileOptions options)     {         name = name ?? throw new ArgumentNullException(nameof(name));         options = options ?? throw new ArgumentNullException(nameof(options));          // Basic initialization in case the options weren't initialized by any other component         options.ContentTypeProvider = options.ContentTypeProvider ?? new FileExtensionContentTypeProvider();         if (options.FileProvider == null && Environment.WebRootFileProvider == null)         {             throw new InvalidOperationException("Missing FileProvider.");         }          options.FileProvider = options.FileProvider ?? Environment.WebRootFileProvider;          var basePath = "wwwroot";          var filesProvider = new ManifestEmbeddedFileProvider(GetType().Assembly, basePath);         options.FileProvider = new CompositeFileProvider(options.FileProvider, filesProvider);     } } 
  3. Make the dependent web application to use your Razor Class Library router. In the ConfigureServices method of Startup Class, add the following line.

    services.ConfigureOptions(typeof(UIConfigureOptions)); 
  4. So, now you can add a reference to your file. ( let's assume it's located at wwwroot/js/app.bundle.js).

    <script src="~/js/app.bundle.js" asp-append-version="true"></script> 
like image 33
Ehsan Mirsaeedi Avatar answered Sep 21 '22 08:09

Ehsan Mirsaeedi