Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nuget package contentFiles not copied to .NET Core project

I'm trying to extract content files from a Nuget package to a project referencing my package.

Based on Justin Emgarten's comment

Packages.config projects use the content folder

Project.json/PackageReference/NETCore SDK projects use the contentFiles folder

So ok great, I created a .NET Core 2.1 Console Application project and followed the NuGet ContentFiles Demystified blog post which was written in 2016 at the time of project.json but should still work nowadays.

I created an image at c:\dev\ContentFilesExample\contentFiles\any\any\images\dnf.png then created a c:\dev\ContentFilesExample\ContentFilesExample.nuspec file and copy pasted the content:

<?xml version="1.0"?>
<package>
    <metadata minClientVersion="3.3.0">
        <id>ContentFilesExample</id>
        <version>1.0.0</version>
        <authors>nuget</authors>    <!-- The NuGet team authored this package -->
        <owners>nuget</owners>      <!-- The NuGet team owns this package -->
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>A content v2 example package.</description>
        <tags>contentv2 contentFiles</tags>
        <!-- Build actions for items in the contentFiles folder -->
        <contentFiles>
            <!-- Include Assets as Content -->
            <files include="**/images/*.*" buildAction="EmbeddedResource" />
        </contentFiles>
    </metadata>
</package>

Then I generated the Nuget package with the command nuget pack ContentFilesExample.nuspec and opened it using Nuget Package Explorer

enter image description here

Great my picture is there as expected.

And now the final non-working step. I install this Nuget package in my .NET Core 2.1 project but the image is missing. No trace of the image in the root directory of my project, neither in the obj folder nor in the bin folder.

I tried to close and re-open visual studio as stated in some comments somewhere but that didn't solve the issue.

I also tried to change my .NET Core project style to PackageReference but again, this didn't solve the issue

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.1</TargetFramework>
        <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="ContentFilesExample" Version="1.0.0" />
    </ItemGroup>

    <ItemGroup>
        <None Update="appsettings.json">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
    </ItemGroup>

</Project>

So what am I doing wrong? Are content files in Nuget packages really supported by .NET Core?

Thank you

like image 446
Jérôme MEVEL Avatar asked Aug 22 '18 03:08

Jérôme MEVEL


People also ask

Where does .NET Core Store NuGet packages?

The global-packages folder is where NuGet installs any downloaded package. Each package is fully expanded into a subfolder that matches the package identifier and version number. Projects using the PackageReference format always use packages directly from this folder.

How do I copy a NuGet package from one project to another?

Simply copy existing packages. config file to your new project. Include this file into the project. Then follow to Package Manager Console and execute Update-Package -reinstall command.


2 Answers

I ended up on this question after hours and hours of googling for a solution, so I decided to write another answer to make things clear because MS docs suck

  1. <files> element in .nuspec file is for the packer. It tells nuget which files to pack (if there are no <files> element in your nuspec - nuget will use the directory naming convention)
  2. <contentFiles> element is for the consumer - it tells how and when to extract the files.
  3. If you want a file to appear in your project after installing - you have to pack it with a target that says contentFiles/any/any where "any/any" part tells nuget it's for ANY language and ANY framework.
  4. (optional) if you also want this file to work with the old nuget mode, that uses packages.config - you have to pack it again, 2nd time, this time - to "content" folder, so older consumers can still use it.

nuspec

  <metadata>
   ...
    <contentFiles>
      <files include="**/myfile.cs" />
    </contentFiles>
  </metadata>
  <files>
      <file src="myfile.cs" target="contentFiles\any\any" /> <!-- this is for new format -->
      <file src="myfile.cs" target="content" /> <!-- this is for the old format -->
  </files>

PS. Some more details in my blog post here

like image 194
Alex from Jitbit Avatar answered Oct 13 '22 11:10

Alex from Jitbit


nupkg should have contentFiles/ directory:
nupkg

Install to netcore project:
enter image description here

It won't be a loose file in the consuming project, it will be an EmbeddedResource when you build the project:
enter image description here

like image 34
Jake Avatar answered Oct 13 '22 13:10

Jake