"Duplicate compile items" error when generating code from "Add Web Reference" in Rider - .net-core

I'm creating a .NET core API that consumes a web service with the Rider IDE.
I created a new csproj FooBar.Service, and added the web reference. The FooBar.Service.csproj file is as follow:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<WCFMetadata Include="Service References" />
</ItemGroup>
<ItemGroup>
<WCFMetadataStorage Include="Service References\FooBar" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="Service References\FooBar\FooBar.svcmap">
<Generator>WCF Proxy Generator</Generator>
<LastGenOutput>FooBar.cs</LastGenOutput>
</None>
<None Include="Service References\FooBar\FooBar.webref" />
<None Include="Service References\FooBar\FooBar.wsdl" />
</ItemGroup>
<ItemGroup>
<Compile Include="Service References\FooBar\FooBar.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>FooBar.svcmap</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Reference Include="System.ServiceModel" />
</ItemGroup>
</Project>
The generated code seems correct, but I have this error:
Duplicate 'Compile' items were included. The .NET SDK includes 'Compile' items from your project directory by default. You can either remove these items from your project file, or set the 'EnableDefaultCompileItems' property to 'false' if you want to explicitly include them in your project file. For more information, see https://aka.ms/sdkimplicititems. The duplicate items were: 'Service References\FooBar\FooBar.cs'
I've read the other question about this issue: the answer is that there are 2 compile items with the same name. If I understand the error message, the file is firstly added by default because it is in the folder of the .csproj, and it is added again by the <Compile Include="Service References\FooBar\FooBar.cs"> item.
I guess that this is a bug of the Rider web service code generation, but what could be a workaround without messing up with the automaticaly generated code? I know that I can deactivate the EnableDefaultCompileItems flag, but I'd prefer not to because I prefer this behavior.
I tried to replace the Include with an Update as seen in this answer, but then I have a bunch of compile error that says: The type or namespace name 'ServiceModel' does not exist in the namespace 'System' (are you missing an assembly reference?) although it is included.

Related

.target file is not applied to the .csproj file when nuget package is released

I'm making a nuget package which only includes references to a bunch of analyzers and a ruleset file.
I am struggling with getting it to add the <CodeAnalyzersRuleSet> tag to the .csproj file during package install.
After searching for a few hours I stumbled upon this 5 year old question which attempts to solve the same thing but I can't get it to work.
I've configured my NuGet project as follows:
Foo.csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Author, Description, ect removed for brevity -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AsyncFixer" Version="1.6.0">
<IncludeAssets>analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.2.0">
<IncludeAssets>analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<IncludeAssets>analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
build\Foo.targets file:
<Project>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)Foo.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
</Project>
And then the build\Foo.ruleset itself.
I run dotnet pack (dotnet version 7.0.102) in order to create the nuget package.
During package install the only thing that happens is that the package is added like a normal <PackageReference>, and I get all the analyser warnings but it doesn't add the ruleset file, and it doesn't add the <CodeAnalyzerRuleSet> tag to the .csproj file.
I've inspected the nuget package and it doesn't include the .targets and .ruleset files unless I add the following to my .csproj file as well:
<ItemGroup>
<None Include="build\**" Pack="True" PackagePath="build\" />
</ItemGroup>
This adds the files to the .nupkg but they are still not added or applied to my project during package install.
Any help or pointers are greatly appreciated.

Using dependency of dependency in .NET Core

I'm trying to understand how dependencies work in .NET Core.
Let's say I have 2 projects. The Project1 has this definition:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Project2\Project2.csproj" />
</ItemGroup>
</Project>
And this single class which uses the Newtonsoft.Json dependency:
public class Wizard
{
public void DoMagic()
{
var settings = Newtonsoft.Json.JsonConvert.DefaultSettings;
}
}
As you can see, it also references Project2, which has the following definition:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>
When I remove the Newtonsoft.Json package reference from the Project1, I would expect it to no longer compile... But it does compile! As it seems, it's able to use the Newtonsoft.Json that is a dependency of Project2.
So I have 2 questions:
I've done my tests with an "internal" project reference for convenience, but does this work the same way with external package references (i.e. NuGet)?
Can anybody explain the rationale here? It seems risky to me, a change of a dependency in any of the dependencies of my project can break my project, if it is using that sub-dependency. In other words, why is this allowed? It seems to be always a bad idea to use implicitly a dependency of a dependency, because it could change and break your code, so why does the framework allow this?
Yes, that's how it works across everything.
You can use PrivateAssets to control this:
https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assets

Including a custom file in your build/publish for a .net core application

How do I include a custom file that is in the root of my project dir to be put into my build/publish folder?
If its a .json file it seems to come through automatically (probably because of .NET config being json)
I have a custom config file that is text based with a .txt extension.
I've tried:
<ItemGroup>
<DotnetPublishFiles Include="customfile.txt"></DotnetPublishFiles>
</ItemGroup>
And
<ItemGroup>
<Content Include="./*.txt" />
</ItemGroup>
As well as
<ItemGroup>
<Content Include="customfile.txt" />
</ItemGroup>
Also:
<_CustomFiles Include="$(MSBuildProjectDirectory)/customfile.txt" />
<DotNetPublishFiles Include="#(_CustomFiles)">
</DotNetPublishFiles>
</ItemGroup>
Nothing seems to work...
I'm using Visual Studio Code and .NET Core 3.1.
Any ideas?
<ItemGroup>
<None Update="customfile.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<ItemGroup>
JSON (as well as other suitable) files are treated the same way by SDK style projects, so for your own custom files you need to ask MSBuild explicitly.
For publishing there is another tag: CopyToPublishDirectory
<ItemGroup>
<None Update="customfile.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
<ItemGroup>

Repackage 3rd party libraries as NuGet package

I am using a 3rd party library which supports .NET Core, but not .NET Standard. They provide separate binary SDKs for each platform they support; win-x86, linux-x64, etc. For each platform there is a CoolSdkDotNetCore.dll, and a coolsdk.dll/so/dylib. The CoolSdkDotNetCore.dll files are indeed different for each platform - they're all exactly the same size, but have different SHA hashes.
For my own sanity I'd like to repackage all this as a single .nupkg using runtime identifiers to pull in the right stuff for a given platform, so that I can build for Windows, docker, etc without having to swap binaries around. I have a project file like so:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>CoolSdk.NetStandard</PackageId>
<Version>1.2.3</Version>
<RootNamespace>coolsdk</RootNamespace>
<AssemblyName>coolsdk</AssemblyName>
</PropertyGroup>
<ItemGroup>
<None Pack="true" PackagePath="runtimes/win-x64/native/coolsdk.dll" Update="windows/x64/coolsdk.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="windows/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/native/libcoolsdk.so" Update="linux/x64/libcoolsdk.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="linux/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
This produces a .nupkg that appears to have everything I need, but consuming projects don't actually get a reference to the CoolSdkDotNetCore assembly. In the bin folder, I see a runtimes folder with the native components, but no lib folders (the lib folders are definitely present in the actual nupkg).
What am I missing here? Do I need to go back and write a nuspec myself instead of trying to use a csproj to generate it all for me, or is there some other trick I can use?
edit:
Changing the library paths above from runtimes/<rid>/lib/netcore to runtimes/<rid>/netcoreapp allows the lib folders to be copied to the bin folder in a consuming project, but I'm still not able to actually reference the assembly. Manually adding a reference to CoolSdkDotNetCore like:
<Reference Include="CoolSdkDotNetCore">
<HintPath>CoolSdkDotNetCore.dll</HintPath>
</Reference>
Generates MSB3245 - Could not resolve this reference....
The answer is to include a single copy of the .NET Core assembly as a "ref". Which one doesn't really matter - this assembly will never be run, only loaded by the IDE and at compile time. At runtime, the correct assembly will be loaded from the runtimes folder. As a final gotcha, nuget will not pack the same file twice; if you have two or more items in the item group with the same value for the Update key, only the last one will actually get added to the final .nupkg. So, picking at random I made a copy of the windows/x64 dll in the root of my project, and updated my csproj thusly:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>CoolSdk.NetStandard</PackageId>
<Version>1.2.3</Version>
<RootNamespace>coolsdk</RootNamespace>
<AssemblyName>coolsdk</AssemblyName>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<None Pack="true" PackagePath="ref/netcoreapp2.1/CoolSdkDotNetCore.dll" Update="CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/native/coolsdk.dll" Update="windows/x64/coolsdk.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="windows/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/native/libcoolsdk.so" Update="linux/x64/libcoolsdk.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="linux/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

WASM WebAssembly FileNotFoundException from System.Private.CoreLib

I am trying to use https://platform.uno/ to build some tools. The WASM (WebAssembly)-Project from uno-platform template will not start due to FileNotFoundExceptions regarding some base Microsoft libs.
I created a new uno-platform APP from uno template. I have updated all NuGet packages to latest version. When I start the wasm web-project I get the following exceptions (at bootstrap i guess):
followed by:
followed by:
Here you can see the Exception class comes from the namespace that was not found in picture 1. It's very strange to me and I don't know whats up anymore.
I guess this is an issue with prerequisites or wrong versions in dependencies somewhere. Does anybody know whats up?
Here is the csproj of the WASM project:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netstandard2.0</TargetFramework>
<WasmHead>true</WasmHead>
<DefineConstants>$(DefineConstants);__WASM__</DefineConstants>
<NoWarn>NU1701</NoWarn>
<StartupObject>Macs3.Calculations.TestTool.Wasm.Program</StartupObject>
<MonoRuntimeDebuggerEnabled>true</MonoRuntimeDebuggerEnabled>
</PropertyGroup>
<ItemGroup>
<Content Include="..\Macs3.Calculations.TestTool.UWP\Assets\*.png" Link="Assets\%(FileName)%(Extension)" />
<Content Include="Fonts\winjs-symbols.woff2" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="WasmCSS\Fonts.css" />
<EmbeddedResource Include="WasmScripts\AppManifest.js" />
</ItemGroup>
<ItemGroup>
<LinkerDescriptor Include="LinkerConfig.xml" />
</ItemGroup>
<ItemGroup>
<!--
This item group is required by the project templace because of the
new SDK-Style project, otherwise some files are not aded automatically.
You can safely remove this ItemGroup completely.
-->
<Compile Remove="Program.cs" />
<Compile Include="Program.cs" />
<Content Include="LinkerConfig.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Uno.UI" Version="1.46.0-dev.2039" />
<PackageReference Include="Uno.Wasm.Bootstrap" Version="1.0.0-dev.298" />
</ItemGroup>
<Import Project="..\Macs3.Calculations.TestTool.Shared\Macs3.Calculations.TestTool.Shared.projitems" Label="Shared" Condition="Exists('..\Macs3.Calculations.TestTool.Shared\Macs3.Calculations.TestTool.Shared.projitems')" />
</Project>

Resources