.NET 7 dependencies and nuget packages managing - asp.net-core

I've started a new .NET 7 project in Visual Studio 2022. The template I used was "ASP.NET Core WebAPI". The project turned out to look like this in the solution explorer:
I can see that there is a dependency upon a series of DLLs in the folder "C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\7.0.2\ref\net7.0". When I browse to this folder and grab, for instance, the "Microsoft.AspNetCore.Http.Abstractions.dll" assembly I see its version as 7.0.22..... which makes sense.
What is weird is that when I click "Manage NuGet Packages" on this project I see absolutely no NuGet package already installed. It looks like this dependency mechanism is something independent of NuGet.
Now I want to create a class library that will encapsulate some common functionality I'd like to share across the projects but it needs to read data from the HttpContext class, which is defined in the "Microsoft.AspNetCore.Http.Abstractions.dll" file. So how should I add this dependency?
Adding it through "dotnet add package Microsoft.AspNetCore.App" command on the class library projects seems like a waste of resources as it adds the entire bundle of dlls and I only care about .Http.Abstractons.dll and it's direct dependencies.
Plus, when I ran the command Visual Studio complained with the warning:
NETSDK1080 A PackageReference to Microsoft.AspNetCore.App is not necessary when targeting .NET Core 3.0 or higher. If Microsoft.NET.Sdk.Web is used, the shared framework will be referenced automatically. Otherwise, the PackageReference should be replaced with a FrameworkReference".
Adding the dll through NuGet worked as Visual Studio was not complaining any more but the version of assembly added was 2.2.0 and not 7.0.2 as in the dotnet package. So technically, the HttpContext referenced in one projects is a different thing to the HttpContext referenced in the other project.
Please help me understand this mechanism and how should I add the dll of interest to my project to be able to access HttpContext in my library.
When should I use dotnet add package and when should I use NuGet packages management? Any good reading on this subject to bring me up to speed from .NET Framework 4.+ to .NET 7 in this area?
As .NET user for the last 10 years or so I feel so lost in the recent developments and find official docs I can find on the web of little use.
I tried adding the Microsoft.AspNetCore.App package through the "dotnet add package" command - Visual Studio complained, plus it pulled the entire bundle of assemblies but I care about only "Microsoft.AspNetCore.Http.Abstractions.dll".
I tried adding the "Microsoft.AspNetCore.Http.Abstractions" NuGet package but the version of assembly added was completely different to the one referenced in the WebAPI project.

What is weird is that when I click "Manage NuGet Packages" on this project I see absolutely no NuGet package already installed.
Those dependencies are determined by the project SDK which can be found in the root element of .csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
...
</Project>
So how should I add this dependency?
For latest versions of .NET you should reference corresponding SDK via FrameworkReference, for example to reference ASP.NET Core components you should add <FrameworkReference Include="Microsoft.AspNetCore.App"/> to library projects .csproj file as mentioned in the docs (and in the warning):
<Project Sdk="Microsoft.NET.Sdk">
<!--... rest of file-->
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<!--... rest of file-->
</Project>

Related

Netcore 2.0 publish is not copying SDK dlls

I am trying to publish a Netcore 2.0 application with MSBUILD.
The published output is missing all the SDK dlls such as Microsoft.AspNetCore.Hosting.dll (there are a lot) so when I try to run the application from command line with dotnet appname.dll I get the error saying that it can't find the referenced dll...
I have published other applications before (not created by me) and the publish copies the dlls and also has a "refs" folder which mine does not have.
So I am pretty sure it's a project configuration issue but I have been searching for hours and there is no information on what I should change.
Turns out there was a nuget reference on my project called Microsoft.AspNetCore.All...
For some reason uninstalling this reference solved the issue and now the publish output contains all the SDK dlls
The ASP.NET Core dlls are part of the runtime store that is included in the runtime & hosting bundle installations so they don't need to be included in the publish output. (note that this is going to change in the 2.1 timeframe)
To disable the use of the ASP.NET Core runtime package store, you can set this in your project file:
<PropertyGroup>
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>

Is msbuild /t:Pack supported in full .Net framework?

Based on documentation https://learn.microsoft.com/en-us/nuget/schema/msbuild-targets, it looks like msbuild now support 2 specific targets for NuGet: Pack and Restore.
I have been able to use Restore properly, but not Pack.
error MSB4057: The target "Pack" does not exist in the project.
Is it supported for traditional .Net project or is it a .Net Core thing only?
I haven't been able to find any documentation stating it clearly.
Regarding required dependencies, I am using
PM> nuget help
NuGet Version: 4.1.0.2450
usage: NuGet <command> [args] [options]
Type 'NuGet help <command>' for help on a specific command.
And
C:\Git>msbuild /version
Microsoft (R) Build Engine version 15.1.1012.6693
Copyright (C) Microsoft Corporation. All rights reserved.
15.1.1012.6693
With
Microsoft Visual Studio Professional 2017
Version 15.2 (26430.12) Release
VisualStudio.15.Release/15.2.0+26430.12
Microsoft .NET Framework
Version 4.6.01586
It is supported out of the box for "SDK-based" projects. There is no project template in VS for .NET Framework libraries using this ""new-style csproj"", but you can create a .NET Standard library project and manually change the TargetFramework property in the csproj file from netstandard1.6 to net461. Note that the project system that is used for these types of project doesn't support many features available in classic .net projects yet (like designers for WinForms, Xaml, edmx).
The resulting project file would look like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
</Project>
Looks like I did not Google enough... this blog post clearly speaks about .Net Core only: http://blog.nuget.org/20170316/NuGet-now-fully-integrated-into-MSBuild.html
Some of the features discussed earlier are not yet fully supported for
packages.config based projects such as defining nuspec metadata in
project files, building packages directly from a project, [...]. We are hard at work to bring full PackageReference support to
these project types. Our goal is to eventually make PackageReference
the default and move away from all other formats.

Missing "BuiltProjectOutputGroupDependencies" building VSIX depending on new simplified csproj

I have a standard VSIX project taking a project dependency on a class library project in the same solution. Everything was building just fine until I switched the class library to the new VS2017RC simplified csproj. The class library builds fine (my dotnet SDK is 1.0.0-preview4-004233), but when trying to build the VSIX I get:
error MSB4057: The target "BuiltProjectOutputGroupDependencies" does not exist in the project.
This obviously looks like an incompatibility with a traditional VSIX csproj expecting something from dependent projects that the new csproj doesn't provide.
Has anyone bumped into this or have any advice on working around it? I'm going to look into removing the project reference and manually referencing the output DLL.
As a related side note, it's unclear which output DLL the VSIX would select from the class library, as the new csproj supports multiple target frameworks.
As stated on the GitHub issue, here's a workaround:
Unload the VSIX project.
Right-click and edit its .csproj file.
Find the <ProjectReference> to the project which started causing the issue.
Add the element <AdditionalProperties>TargetFramework=net452</AdditionalProperties>, using the correct .NET Framework version you target in the referenced project.
Reload and rebuild the VSIX proejct.
I believe you may be encountering the same issue I had when I tried to reference my Visual Studio Extension from a .NET Standard library that was targeting multiple frameworks. There is a GitHub issue dotnet/sdk#433 about it.
What I had to do was remove my other targets. In my case, I had:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.3;net46</TargetFrameworks>
</PropertyGroup>
...
</Project>
And I had to modify it to only target netstandard1.3 (since it is compatible with .NET 4.6 according to the .NET Standard chart) and my VSIX targets .NET 4.6.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>
...
</Project>

Nuget Content Files in .Net core solution not getting copied when installing through Nuget

I'm not able to copy the content static files in my .Net core web application project that I added when creating the nuget package using nuget package explorer. Same thing get copied correctly in .Net framework project template but not in .net core template. I'm using VS 2015 update 3.Am i Missing something here? Any help would be greatly appreciated.
Below is my snapshot of content file structure.
There is a nuget blog post about this, and it just isn't supported at this time.
Supported Project Types
This feature is only for packages that will be installed to projects that are managed using a project.json file. Currently only two projects types are managed by a project.json.
UWP apps
Portable class libraries
The contentFiles option is not available for other project types.
It's really a pity this basic functionality has been excluded from the .net Core projects. Especially because PCL is supported, which is a subset of a .net Core project.
There are quite some issues on GitHub about this, and it's very unclear whether or not this feature is coming back any time soon.
It seems it is still not supported. Only way to "hack" it is with MSBuild Targets and Build events.
According to this documentation:
build
MSBuild .targets and .props files Automatically inserted into
the project file or project.lock.json (NuGet 3.x+).
So to make it work with any file, e.g.: "config.xml" as Nuget Static Content:
Create your XY.nuspec file (as you would normally)
Include config.xml into the Nuget: <file src="config.xml" target="contentFiles\any\any\config.xml" />
Add a new .targets file XY.targets
Include new XY.targets file into your package to the "build" folder. <file src="XY.targets" target="build"/>
Content of the XY.targets file
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ContentFilesPath>$(MSBuildThisFileDirectory)..\contentFiles\any\any\</ContentFilesPath>
</PropertyGroup>
<Target Name="CopyConfigs" BeforeTargets="PreBuildEvent">
<Copy SourceFiles="$(ContentFilesPath)\config.xml" DestinationFiles="$(ProjectDir)config.xml" SkipUnchangedFiles="true" Condition="!Exists('$(ProjectDir)config.xml')"></Copy>
</Target>
</Project>
After packaging and installing the Nuget this MSBuild Target will be part of the Cached package and will run on each build (currently before build).
Issues with this solution:
Added files still linked until you build your solution. During the build paheses (BeforeTargets="") files are copied. Until this files still are just linked!!!
If you set up your content files to have Build actions and be copied to the Output directory of the project those settings will be lost!
Unfortunately this is the best solution for now.
Some public nuget packages (e.g. https://www.nuget.org/packages/NUnit3TestAdapter/3.10.0 or https://www.nuget.org/packages/Selenium.WebDriver.ChromeDriver/) can copy files. I've tried to investigate it (https://github.com/nunit/nunit3-vs-adapter and https://github.com/jsakamoto/nupkg-selenium-webdriver-chromedriver). But it seems, they have implemented very tricky workaround
After reading this post I came up with a work around. I created a .Net assembly project and completely emptied it out of all content. Then I moved the project into the same directory as the project for the .Net Core Web application. Instead of adding the NuGet package reference from the web application, I add it from the .Net assembly project. All of the files are correctly copied into the directory and are automatically added to the web project, since they share the same directory. This solution feels very dirty, but it is allowing me to manage static files with a NuGet package for a .Net Core Web project.

Reference third-party class libraries

I am working with .Net Core 1.0 (running under the .Net Framework 4.6.1, non-portable).
I need to include some DLLs that are from a locally-built GitHub project. When I build those projects, and then attempt to "Add Reference" to the resulting DLLs, I get a message saying I can't add them to a Core project directly.
After more research, I found a lot of information regarding "private" NuGet packages. However, those seem overly complex / overly engineered.
Is there any way I can do the following:
Without having to go through the headache of creating a private NuGet repository, can I just "add reference" to the built assemblies that are sitting in the bin folder of the NuGet projects I pulled?
I really don't want to have to build a local-only NuGet package. Mostly because I've already wasted too much time on this issue, and because I read this entire concept is about to be scrapped and turned into something else (sounds familiar by now)... such as the Roslyn-based build system on GitHub.
My current state:
Visual Studio Professional 2015
.Net Core 1.0.1
.Net Core 1.0.1 Tooling Preview 2
No, as for now you have to create a nuget package before and restore it via Nuget. You can use a simple folder as NuGet source, so if you put your compiled NuGet package in C:\packages, you can add this as a source to NuGet (while in the NuGet UI, click the settings Icon and add the folder as new source).
This may change with the next release of ASP.NET Core (1.1), as the .NET/ASP.NET Core team is working to move from *.xproj to *.csproj files.
One of the reasons why you need to use nuget is because it can contain multiple targets and project.json allows you to target multiple platforms (i.e. net452 and netcoreapp1.0).