nuspec contentFiles not added to a project

2.1k views Asked by At

I have a web project (mvc5) with a project.json inside.

Also, I have a nuget package. Inside this package (besides the dll reference) I have some Content files (cshtml files, css, javascript etc).

There are 2 goals to achieve:

  • After installing the package to the project I want to get Content Files included to the project.
  • After Building the project I want nuget to restore the content files

The nuspec file:

<?xml version="1.0"?>
    <package>
      <metadata>
        /.../

        <dependencies>
            <group targetFramework="net461">
              /.../

           </group>
        </dependencies>
          <contentFiles>
        <files include="**/*.*" flatten="false" copyToOutput="false" buildAction="Content" /> 
      </contentFiles>
      </metadata>
      <files>
         /.../
    <file src="..\src\Content\**\*.*" target="contentFiles\any\any\Content" /> 
    <file src="..\src\Views\**\*.*" target="contentFiles\any\any\Views" /> 
      </files>
    </package>

Well, Visual Studio is adding nuget package with no issues. The reference is also included. But the content is always missing. The content files are not copied from the /packages/ folder and are not included to the project. The same is when I build the project - it just copies the dll and does not touch content files from the package at all.

It only works if I have copyToOutput="true", but all content goes to bin folder, of course.

The reason why I need to restore the content files is that the files from the nuget package are ignored by a tfs 'ignore file' (.tfignore). I don't want to have these content files to be a part of the web project in TFS. However, of course, TFS build server fails to build the project, because some content files are missing (the files from the package). So I want nuget on the build server to restore the content files before it stats building the project.

Any idea how to get this work if it is possible? Or maybe this is not possible and I must have content files to be included to the project?

3

There are 3 answers

0
Martin Ullrich On

This is by design. NuGet packages are no longer supposed to modify the project's source but only add to its built output or build process (in addition to .NET libraries). The content folder for adding sources to the project is only continued to be supported for packages.config based projects since it would be a breaking change for existing projects, but projects using project.json or PackageReference (VS 2017) get the new behaviour.

0
razgoolyy On

you could add a msbuild target to your package. in this target you can execute the nuget restore command...

example:

<?xml version="1.0"?>
<package >
    <metadata>
    <!-- ... -->
    </metadata>
    <files>
      <!-- Include your MSBuild target to \build -->
      <file src="build\myNuGetRestoreTarget.targets" target="build" />
    </files>
</package>

see: https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package

0
Jones On

I was in the situation. Here's how I handled it.

  1. Don't keep your files as content, content files are added to project files. Rename the target to something else. I kept it as drop. Your nuspec file should be like:

     <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
         <metadata>
             <id>ID</id>
             <version>1.0</version>
             <title>Title</title>
             <authors>J</authors>
             <owners>J</owners>
             <requireLicenseAcceptance>false</requireLicenseAcceptance>
             <description>Binary Files such as images, fonts, icons and svgs</description>
             <copyright>J</copyright>
         </metadata>
         <files>
             <file src="..\..\Internal.Resources.targets" target="build" />
             <file src="..\..\**\*.*" target="drop" exclude="**\*.targets"/>
         </files>
     </package>
    
  1. Keep a target file as one of your drop file. Like following:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <ItemGroup>
       <RequiredFiles Include="$(MSBuildThisFileDirectory)..\drop\**\*.*" />
       <None Include="@(RequiredFiles)">
        <Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       </None>
      </ItemGroup>
     </Project>
    

Now your nuget install will just extract the content in packages folder, add target to your project. When you build, the targets will fetch files from package directory and put in build directory.