Closed chrisdaiii closed 1 year ago
Thank you for filing this issue. Could you be able to provide us small repro code for both cases? So, I can compare them?
Note: Both ProjectA-net6.0 and ProjectB-net48 refer to the local ProjectB Nuget package, please pack ProjectB and ProjectC into a directory, and modify the NuGet.config file at the same time.
Please help me to understand what is going on, thank you very much!
After you complete the above operations, compile the entire solution, you can see the ProjectA-net6.0\bin\Denug\net6.0\net6.0\1.txt file, but there is no ProjectA-net48\bin\Debug directory.
After you complete the above operations, compile the entire solution, you can see the ProjectA-net6.0\bin\Denug\net6.0\net6.0\1.txt file, but there is no ProjectA-net48\bin\Debug directory.
I think it's by design, I'll check and let you know soon.
After you complete the above operations, compile the entire solution, you can see the ProjectA-net6.0\bin\Denug\net6.0\net6.0\1.txt file, but there is no ProjectA-net48\bin\Debug directory.
I think it's by design, I'll check and let you know soon.
ok, thanks.
Hey, We don't think there's a NuGet bug here. The props in the buildtransitive folder is getting included in the project which is where the NuGet responsibility ends. The implementation of the props file is where the issue is. I'm gonna close this issue, but I'm happy to help you improve the authoring of the props file.
TargetFramework is an opaque string, which is not something that's available in both SDK (or .NET projects) and old style csproj (.NET Framework projects). The .NET Framework project does not have TargetFramework, so it will never evaluate correctly.
I.e TargetFramework
which is used in ProjectC.prop
is not really thing for netframework(net48) unless you define it, you can read more from here.
For net6.0
dotnet case it understands TargetFramework
because you defined it in line 3.
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>ProjectA_Core</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Since net4.8
netframework doesn't have TargetFramework
, but it you can use TargetFrameworkMoniker
, TargetFrameworkVersion
instead.
<Project>
<>
<ItemGroup Condition="'$(TargetFrameworkMoniker)' == '.NETFramework,Version=v4.8'">
<Content Include="$(MSBuildThisFileDirectory)..\contentFiles\any\net48\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Link>net48\%(Filename)%(Extension)</Link>
</Content>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<Content Include="$(MSBuildThisFileDirectory)..\contentFiles\any\net6.0\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Link>net6.0\%(Filename)%(Extension)</Link>
</Content>
</ItemGroup>
<PropertyGroup>
<OutputType>Library</OutputType>
</PropertyGroup>
</Project>
But we don't recommend doing this way, because this kind of fragile implementation, it doesn't take into account of the package compatibility, next time if you want to extent above for net7.0
then you need to manually add it even though you don't need to. Probably you need to add for by platform too next time, like net7.0-android
etc with above.
Instead, please use asset control (https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assets).
<ItemGroup>
<PackageReference Include="ProjectB" PrivateAssets="none" Version="1.0.0" />
<PackageReference Include="ProjectY" IncludeAssets="contentFiles" Version="2.0.0" />
<PackageReference Include="ProjectZ" IncludeAssets="build;buildTransitive" Version="3.0.0" />
</ItemGroup>
Above is more flexible and scalable in long run, see more from here.
Thank you for helping me figure out what's wrong, thank you very much, wish you a good day every day.
Hey, We don't think there's a NuGet bug here. The props in the buildtransitive folder is getting included in the project which is where the NuGet responsibility ends. The implementation of the props file is where the issue is. I'm gonna close this issue, but I'm happy to help you improve the authoring of the props file.
TargetFramework is an opaque string, which is not something that's available in both SDK (or .NET projects) and old style csproj (.NET Framework projects). The .NET Framework project does not have TargetFramework, so it will never evaluate correctly. I.e
TargetFramework
which is used inProjectC.prop
is not really thing for netframework(net48) unless you define it, you can read more from here.For
net6.0
dotnet case it understandsTargetFramework
because you defined it in line 3.<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <RootNamespace>ProjectA_Core</RootNamespace> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup>
Since
net4.8
netframework doesn't haveTargetFramework
, but it you can useTargetFrameworkMoniker
,TargetFrameworkVersion
instead.<Project> <> <ItemGroup Condition="'$(TargetFrameworkMoniker)' == '.NETFramework,Version=v4.8'"> <Content Include="$(MSBuildThisFileDirectory)..\contentFiles\any\net48\**"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> <Link>net48\%(Filename)%(Extension)</Link> </Content> </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net6.0'"> <Content Include="$(MSBuildThisFileDirectory)..\contentFiles\any\net6.0\**"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> <Link>net6.0\%(Filename)%(Extension)</Link> </Content> </ItemGroup> <PropertyGroup> <OutputType>Library</OutputType> </PropertyGroup> </Project>
But we don't recommend doing this way, because this kind of fragile implementation, it doesn't take into account of the package compatibility, next time if you want to extent above for
net7.0
then you need to manually add it even though you don't need to. Probably you need to add for by platform too next time, likenet7.0-android
etc with above.Instead, please use asset control (https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assets).
<ItemGroup> <PackageReference Include="ProjectB" PrivateAssets="none" Version="1.0.0" /> <PackageReference Include="ProjectY" IncludeAssets="contentFiles" Version="2.0.0" /> <PackageReference Include="ProjectZ" IncludeAssets="build;buildTransitive" Version="3.0.0" /> </ItemGroup>
Above is more flexible and scalable in long run, see more from here.
Sorry to bother you, I want to ask you a question, if I use asset control as you said (not applicable to .props files), then my ProjectA will not have 1.txt 2.txt 3.txt files, These files are all in ProjectC, ProjectB refers to ProjectC, and ProjectA refers to ProjectB.
NuGet Product Used
Other/NA
Product Version
dotnet 7.0.2 Nuget 6.5.0.136
Worked before?
No response
Impact
It's more difficult to complete my work
Repro Steps & Context
Say I have the following project structure:
ProjectC.csproj
ProjectC.props:
Both ProjectB and ProjectC are Nuget packages, and ProjectA only references ProjectB.
When my ProjectA is a Framework project (net48), the buildTransitive of the indirectly dependent ProjectC fails, and the content files will not be copied to the output directory of ProjectA, but when my ProjectA project is an SDK-style .net core When projecting, everything is normal.
I want to know why when the .net core project indirectly depends on the Nuget package, the dependency file will be copied to the output directory normally, but the .net Framework project will not. Thanks!
Verbose Logs
No response