最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

.net - Static content and CSS isolation bundles from dynamically added Razor Class Library not working - Stack Overflow

programmeradmin0浏览0评论

Using .NET 9 and a Blazor web app (with server interactive rendering mode), I'm struggling to get static assets (or CSS isolation bundles) from a Razor class library to work with my Blazor web app.

I have followed Microsoft's instructions and my .razor file has a .razor.css as a child. In addition I've created a wwwroot with a styles2.css file in it.

The RCL is dynamically loaded through

app.MapRazorComponents<App>().AddAdditionalAssemblies()

The RCL is definitely loaded as a page defined in Components/Pages/MyPage.razor in the RCL, using @page /myurl, is accessible from /myurl.

When running the app I can find neither the bundle nor the CSS file. I've tried various version of the supposed syntax, but none work:

  • _content/MyRclAssemblyName/MyRclAssemblyName.bundle.scp.css
  • _content/MyRclAssemblyName/styles2.css
  • MyRclAssemblyName/MyRclAssemblyName.bundle.scp.css
  • MyRclAssemblyName/styles2.css
  • Probably more but I've fotten

Adding this to the WebApplicationBuilder has no effect:

builder.WebHost.UseWebRoot("wwwroot");
builder.WebHost.UseStaticWebAssets();

Though this is not really surprising as per the documentation

running the consuming app from build output (dotnet run), static web assets are enabled by default in the Development environment.

My suspicion is that because this is added through .AddAdditionalAssemblies() that this creates some weird scenario where you need additional configuration that is not documented or hidden in a way that I've overlooked it.

How can I use static assets, or CSS bundles, from a Razor class library that is dynamically loaded through .AddAdditionAssembles() and not referenced directly?

Using .NET 9 and a Blazor web app (with server interactive rendering mode), I'm struggling to get static assets (or CSS isolation bundles) from a Razor class library to work with my Blazor web app.

I have followed Microsoft's instructions and my .razor file has a .razor.css as a child. In addition I've created a wwwroot with a styles2.css file in it.

The RCL is dynamically loaded through

app.MapRazorComponents<App>().AddAdditionalAssemblies()

The RCL is definitely loaded as a page defined in Components/Pages/MyPage.razor in the RCL, using @page /myurl, is accessible from /myurl.

When running the app I can find neither the bundle nor the CSS file. I've tried various version of the supposed syntax, but none work:

  • _content/MyRclAssemblyName/MyRclAssemblyName.bundle.scp.css
  • _content/MyRclAssemblyName/styles2.css
  • MyRclAssemblyName/MyRclAssemblyName.bundle.scp.css
  • MyRclAssemblyName/styles2.css
  • Probably more but I've fotten

Adding this to the WebApplicationBuilder has no effect:

builder.WebHost.UseWebRoot("wwwroot");
builder.WebHost.UseStaticWebAssets();

Though this is not really surprising as per the documentation

running the consuming app from build output (dotnet run), static web assets are enabled by default in the Development environment.

My suspicion is that because this is added through .AddAdditionalAssemblies() that this creates some weird scenario where you need additional configuration that is not documented or hidden in a way that I've overlooked it.

How can I use static assets, or CSS bundles, from a Razor class library that is dynamically loaded through .AddAdditionAssembles() and not referenced directly?

Share Improve this question edited Feb 2 at 17:10 TheHvidsten asked Feb 2 at 15:48 TheHvidstenTheHvidsten 4,4583 gold badges34 silver badges72 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

Maybe try this. Program.cs :

and in your page:

This script is from an RCL I published as a Nuget package.

Extra bonus: If you need to use pages from an RCL you will need to declare them to the router.

Routes.cs:

If this doesn't work, please share your code.

What I'm asking for doesn't seem possible for dynamically loaded RCLs according to this issue: https://github/dotnet/aspnetcore/issues/33284 It is a few years old, but seems to still hold true: Feel free to add answers if this changes.

What I ended up doing was marking all content in my wwwroot folder as "Embedded resource", and creating a middleware to serve the content.

Making files an "Embedded resource" looks like this in the .csproj file:

<ItemGroup>
  <Content Remove="wwwroot\styles.css" />
  <EmbeddedResource Include="wwwroot\styles.css" />
</ItemGroup>

This is the middleware (code is shortened for brevity. Add null checks and other validation as needed!):

public class EmbeddedResourceMiddleware(RequestDelegate next)
{
    private readonly string _prefix = "_embeddedResource";

    public async Task Invoke(HttpContext context)
    {
        if (!context.Request.Path.Value.StartsWith($"/{_prefix}/")))
        {
            await next(context);
            return;
        }

        string[] pathSegments = context.Request.Path.Value.Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

        string assemblyName = pathSegments[1];
        Assembly assembly = GetYourAssemblyHere(assemblyName);

        string filePath = string.Join('/', pathSegments.Skip(2));
        string resourceName = "wwwroot." + filePath.Replace('/', '.');
        string resourceFullName = assembly.GetManifestResourceNames()
                .FirstOrDefault(name => name.EndsWith(resourceName));

        await using Stream stream = assembly.GetManifestResourceStream(resourceFullName);

        string contentType = GetContentType(resourceName);
        context.Response.ContentType = contentType;
        await stream.CopyToAsync(context.Response.Body);

    }

    private static string GetContentType(string fileName)
    {
        var provider = new FileExtensionContentTypeProvider();
    
        if (!provider.TryGetContentType(fileName, out string contentType))
        {
            contentType = "application/octet-stream";
        }

        return contentType;
    }
}

And inserted it into the middleware pipeline. Inserted right after UseStaticFiles() should hopefully allow it to behave just like any other static file:

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
WebApplication app = builder.Build();
...
app.UseStaticFiles()
app.UseMiddleware<EmbeddedResourceMiddleware>();
...

Now I can make a request to /_embeddedResource/MyRclAssemblyName/styles.css and get the stylesheet from the wwwroot folder in my RCL.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论