Posted on 01/10/2025 11:53:06
From Chatgpt:
I had a close look at your project file and the behavior you describe, and a couple of things stand out that might explain both the missing files and the null reference on version.
1. contentFiles in NuGet is tricky
In .NET Core / .NET 8, contentFiles doesn’t behave the same way as the old content folder did in NuGet.
-
contentFiles is meant for source files or assets that get included into a project when it references your package.
-
But in your case, Dynamicweb’s app system expects physical files under /Files in the application root, not just entries in the consuming project’s build. NuGet doesn’t automatically copy them to your Dynamicweb instance.
That explains why you see the package install correctly but no files show up in Files.
Fix: You’ll probably want to package them as content (legacy style) or use a targets file inside the NuGet package to copy them at install-time to the Files folder. With contentFiles alone, nothing will land in your Dynamicweb /Files.
2. Null reference on version in “Installed Apps”
Dynamicweb’s App Store integration looks at the package metadata (<Version> and nuspec info).
-
You have <VersionPrefix> and some conditional <Version> properties, but note: NuGet will only use the evaluated <Version> at pack time. If that doesn’t resolve correctly, the .nuspec might end up with an empty <version/>.
-
If the version is missing, Dynamicweb will throw a null reference when trying to display it in Installed Apps.
Try forcing a simple static version to confirm:
<PropertyGroup>
<Version>1.0.0</Version>
</PropertyGroup>
Build and repack. If the error disappears, your version condition logic was the culprit.
3. Small details in your .csproj
-
<PackageCopyToOutput> is not a valid MSBuild property in this context. The correct way is <CopyToOutputDirectory>Always</CopyToOutputDirectory> or PreserveNewest.
-
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> is rarely needed in modern SDK-style projects. It can be dropped unless you’re debugging dependency resolution.
-
<FrameworkReference Include="Microsoft.AspNetCore.App" /> is redundant with net8.0. It doesn’t hurt, but you don’t need it.
Recommended adjustments
Try this in your .csproj:
<ItemGroup>
<!-- Include all Files folder content in the NuGet package -->
<Content Include="Files\**\*.*" Pack="true" PackagePath="content\Files\%(RecursiveDir)%(Filename)%(Extension)">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<PropertyGroup>
<!-- Simple explicit version for testing -->
<Version>1.0.0</Version>
</PropertyGroup>
Notice the difference:
Then repack and reinstall.
Why this matters for Dynamicweb apps
Dynamicweb’s “Installed Apps” list isn’t just NuGet—it’s reading from its own app system layered on top. It expects:
NuGet’s modern contentFiles won’t do that for you, so you need either:
If you want, I can sketch a .targets file that copies your Files contents into wwwroot/Files (or Dynamicweb’s Files folder) automatically when the NuGet is installed. Would you like me to?
YES!
Perfect, let’s wire this up properly.
The trick is: a .targets file inside your NuGet package can hook into the build of the consuming project and copy your Files folder into Dynamicweb’s /Files folder.
Here’s how you can do it:
1. Add a .targets file to your project
Create a file called MarkdownToolkit.targets (name it after your package) in your project root:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyMarkdownToolkitFiles" AfterTargets="Build">
<!-- Source: content files inside the package -->
<ItemGroup>
<MarkdownToolkitFiles Include="$(MSBuildThisFileDirectory)..\content\Files\**\*.*" />
</ItemGroup>
<!-- Destination: Dynamicweb's Files folder -->
<Copy
SourceFiles="@(MarkdownToolkitFiles)"
DestinationFolder="$(MSBuildProjectDirectory)\Files\%(RecursiveDir)"
SkipUnchangedFiles="true" />
</Target>
</Project>
This says:
-
After build, take everything from the NuGet package’s content\Files directory.
-
Copy it into the consuming project’s /Files folder.
2. Include this .targets file in your NuGet package
Update your .csproj so it packs the .targets file correctly:
<ItemGroup>
<None Include="MarkdownToolkit.targets" Pack="true" PackagePath="build\MarkdownToolkit.targets" />
</ItemGroup>
Now, when someone installs your NuGet, MSBuild will import your .targets automatically.
3. Keep your Files folder packaging clean
Instead of contentFiles, switch back to content:
<ItemGroup>
<Content Include="Files\**\*.*" Pack="true" PackagePath="content\Files\%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
That way, NuGet places your files under content/Files in the .nupkg, and the .targets file will copy them into the Dynamicweb solution’s /Files.
4. Test the flow
You should see your files appear in Files\ in the consuming Dynamicweb site, and the Installed Apps view should now display the correct version (after fixing the <Version> property as I mentioned earlier).
This approach is pretty standard for packages that need to drop “physical assets” into a web project (like JS, CSS, or, in your case, app files).
Do you want me to also show you a minimal nuspec override that ensures Dynamicweb sees the correct metadata (version, description, etc.), so you can avoid the null reference issue altogether?