Microsoft.AspNetCore.Mvc dependency and ASP.NET Core 3 - .net-core-3.0

We have existing libraries that depend on MVC, for example to provide custom action filters. These libraries are published as Nuget.
Until now, we just referenced Microsoft.AspNetCore.Mvc from the library, so that we could use the respective types (such as ActionFilterAttribute). But starting with ASP.NET Core 3, Microsoft stopped publishing many Nuget packages as indicated by the upgrade guide, among them Microsoft.AspNetCore.Mvc.
How should libraries that depend on MVC reference MVC, starting with ASP.NET Core 3?

This is outlined in section library multi-targeting in the upgrade guide:
The library must target both .NET Core 3 and .NET Standard 2.0, and use conditionals to either use a PackageReference or FrameworkReference:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.2" />
</ItemGroup>
</Project>

According to the documentation in the link you provided, you can either target the Microsoft.NET.Sdk.Web SDK which will reference Microsoft.AspNetCore.App shared framework implicitly:
Projects that target the Microsoft.NET.Sdk.Web SDK implicitly reference the Microsoft.AspNetCore.App framework.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
...
</Project>
Or explicitly for other SDKs:
Projects that target Microsoft.NET.Sdk or Microsoft.NET.Sdk.Razor SDK, should add an explicit FrameworkReference to Microsoft.AspNetCore.App.
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
...
</Project>
Are there certain libraries that you depended on that aren't included in the Microsoft.AspNetCore.App shared framework?

Related

Can't add C# WinRT component to C++ WinRT UWP project

The bounty expires in 3 days. Answers to this question are eligible for a +50 reputation bounty.
sz ppeter wants to draw more attention to this question.
I am following the guide here, but I am using a C++ WinRT UWP project to consume the C# component instead of the C++ WinRT console project in the guide.
However, it failed to add the C# component project as a project reference.
My .csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TargetFramework>net6.0-windows10.0.22000.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<CsWinRTComponent>true</CsWinRTComponent>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.1" />
</ItemGroup>
</Project>
My Solution structure:
I also tried to add the winmd file from the C# component, but I am stuck when adding
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>WinRT.Host.dll</Path>
<ActivatableClass ActivatableClassId="CSharpComponent.Class1" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
to package.appxmanifest. It fails to compile with this

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

.NET Core 3 Invalid reference from Common Library

I need 2 assemblies for my .NET Core 3 WPF App - System.Windows.Forms and System.Drawing.Common.
When I try to add them as references in Visual Studio 2019 from the common shared folder (C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.0.0) i get an exception message box saying "The reference is invalid or unsupported".
I would expect this kind of thing to happen with framework mismatches, but this is from the dotnet core v3 shared folder, so everything should line up.
Is there any particular trick to adding these references that I am unaware of?
csproj file:
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="logo.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
In the .NET Core, the project system does not handle well binary assembly references. It may not always work and is an unsupported and unrecommended way to reference assemblies. The proper way is to use package references or framework references. The latter are expressed at the top level of the project via the Sdk attribute i.e. <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">.
First of all, you should not add assembly references but add package references either manually or using the package manager. The reference to System.Drawing.Common assembly for .NET Core 3.0 target should look as follows:
<PackageReference Include="System.Drawing.Common" Version="4.6.0" />

Dotnet publish with .NET core 2.0 and .NET framework projects

I'm hoping someone has some advice on the best way to use Teamcity to build and publish a solution that has both .NET Core/standard 2.0 projects and .NET framework 4.6.x projects in it.
Currently, I can build the project, run tests, but I can't figure out a way to publish it via the dotnet-cli. We have a relatively large solution, approximately 75 projects in .NET core/standard and 5 or some framework projects. Running dotnet publish on our solution results in the following error on the .NET framework projects:
error: C:\Program Files\dotnet\sdk\2.0.3\Microsoft.Common.CurrentVersion.targets(3861,5): error MSB4062: The "Microsoft.Build.Tasks.ResolveManifestFiles" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a. Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
It would be ideal if the cli could attempt to ignore publishing the .NET Framework projects, but it doesn't seem to be possible. I'm thinking about writing a powershell script to check all csproj files in our solution for an appropriate TargetFramework value (i.e netstandard2.0/netcoreapp2.0), and publish them individually, but maybe someone knows a better way?
If anyone is facing the same issue, you need to restructure your csproj file as suggested by #nvoigt.
You can follow the steps as described in the post Old csproj to new csproj
You can start clearing out your csproj file and start with below format.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net462</TargetFramework> // if your target is 4.6.2
</PropertyGroup>
</Project>
And now you can add remaining of your dependency like below.
...
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.4" />
<PackageReference Include="Microsoft.Azure.Storage.Blob" Version="11.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
<PackageReference Include="Microsoft.Azure.KeyVault" Version="2.0.6" />
<PackageReference Include="NLog" Version="4.7.5" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.5" />
</ItemGroup>
...
you can find more details on the post.

Patch version of ASP Core (preview 4) with AppVeyor

How to patch Asp.Net Core project (csproj) in order to build versioned binaries with AppVeyor?
Is there a way to apply versioning separately for AssemblyVersion and FileVersion?
AppVeyor has predefined step to patch AssemblyInfo.cs file, but it isn't included into project and functionality of AssemblyInfo moved to csproj file, therefore it's not clear how to deal with versioning.
Appreciate you help!
As .NET Core .csproj is a regular XML you can use PowerShell script to update the version information in it. For example, you might have the following MyProject\MyProject.csproj:
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
<Version>1.2.3.4</Version>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />
</ItemGroup>
</Project>
Then on AppVeyor the script patching <Version> would be the following:
$xmlPath = "$env:appveyor_build_folder\MyProject\MyProject.csproj"
$xml = [xml](get-content $xmlPath)
$propertyGroup = $xml.Project.PropertyGroup | Where { $_.Version}
$propertyGroup.Version = $env:appveyor_build_version
$xml.Save($xmlPath)

Resources