0

I'm trying to create a Nuget package that will copy some files into the wwwroot folder of the application, but I can't seem to get it to work despite reading the documentation and looking at other questions online. Here is what I have so far.

<?xml version="1.0"?>
<package >
  <metadata>
    <id>...</id>
    <version>...</version>
    <title>...</title>
    <authors>...</authors>
    <requireLicenseAcceptance>...</requireLicenseAcceptance>
    <description>...</description>
    <contentFiles>
      <files include="**/*.*" copyToOutput="true" buildAction="EmbeddedResource" />
    </contentFiles>
  </metadata>
  <files>
    <file src="ProjectName\bin\Release\**.dll" target="lib" />
    <file src="ProjectName\wwwroot\**.*" target="content\wwwroot" />
    <file src="ProjectName\wwwroot\**.*" target="contentFile\any\any\wwwroot" />
  </files>
</package>

It puts the files into the content and contentFile folders of the Nuget package as expected, but when referenced if does not copy the files into the project.

2 Answers2

0

Copying files into the project's source directory is not supported and has been a discouraged practice for classic projects.

However, the contentFiles section is meant to include files logically into the project so they can affect the built output. buildAction="Content" will add the files to the build and publish output. This allows to add content to a project without modifying its sources.

Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217
  • I get not wanting to have side affects on the referencing project, but then what is the proper way to package a project then if it includes DLLs and JavaScript and CSS that needs to be in the wwwroot folder? I found a workaround that embeds the resources and then copies them where they need to go, but something less custom would be ideal. – Kevin Ackerman Aug 04 '17 at 00:21
  • Why does it need to go to `wwwroot`? there's no guarantee the hosting asp.net core application even has that folder or is configured to host static files. Swashbuckle for example embeds their UI related files and allows to configure a service into the application pipeline that serves them ([source](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/Application/SwaggerUIBuilderExtensions.cs#L9)) – Martin Ullrich Aug 04 '17 at 07:20
0

So, after checking the suggested link and the rest of the internet, here is the solution I came up with.

public static class ApplicationBuilderExtensions
{
    public static IApplicationBuilder UseMyApp(this IApplicationBuilder app) => UseMyApp(app, null);

    public static IApplicationBuilder UseMyApp(this IApplicationBuilder app, Action<Options> setupOptions)
    {
        var options = new Options();
        setupOptions?.Invoke(options);

        app.UseStaticFiles(new StaticFileOptions
        {
            RequestPath = $"/{options.RoutePrefix}",
            FileProvider = new EmbeddedFileProvider(Assembly.Load(new AssemblyName("MyAssembly")), "MyAssembly.EmbeddedResourcesFolder")
        });

        return app;
    }

    public class Options
    {
        internal Options() { }

        public string RoutePrefix { get; set; } = "defaultRoutePrefix";
    }
}

Then, in your html you can reference the static files by doing something like this.

<link rel="stylesheet" href="~/routePrefix/fileName.extension" />

It is not technically an answer to my question as stated, but it is clear now that what I was asking to do is not best practice - this is a much better way to do it.

  • I'm not sure where this "best practice" is coming from. Serving static files from a directory can be a far better solution in my opinion to embedded resources. Serving a static directory of files can be optimized in many many ways (nginx, cdn, web.config static file module, etc...) and never need to hit the asp.net pipeline. In a modular application, I would re-consider serving static assets as embedded files, as a primary strategy. – matt Nov 28 '17 at 03:25