'dotnet restore' vs. 'nuget restore' with TeamCity

.NetMsbuildNugetTeamcity

.Net Problem Overview


I have an ASP.NET Core project that builds properly with Visual Studio, but it doesn't build under MSBuild.

It doesn't find all the common libraries (system, etc.).

I'm using TeamCity and part of the build process is a nuget restore.

I tried to do the same steps as TeamCity, but manually with MSBuild, and it failed, not finding the libraries.

I added a dotnet restore step and then it worked.

So, what is the difference between a nuget restore and a dotnet restore?

.Net Solutions


Solution 1 - .Net

Both nuget restore and dotnet restore are roughly the same: They perform a NuGet restore operation.

The only difference: dotnet restore is a convenience wrapper to invoke dotnet msbuild /t:Restore which invokes an MSBuild-integrated restore. This only works on MSBuild distributions that include NuGet, such as Visual Studio 2017 (full Visual Studio, build tools) or Mono 5.2+ (=> msbuild /t:Restore) and the .NET Core SDK which provides this convenience command.

At the moment, there are two ways of how NuGet packages can be used in projects (three actually, but let's ignore project.json on UWP for the moment):

  • packages.config: The "classic" way of referencing NuGet packages. This assumes NuGet is a separate tool and MSBuild doesn't know anything about NuGet. A NuGet client such as nuget.exe or Visual Studio-integrated tooling sees the packages.config file and downloads the referenced packages into a local folder on restore. A package install modifies the project to reference assets out of this local folder. So a restore for a packages.config project only downloads the files.
  • PackageReference: The project contains MSBuild items that reference a NuGet package. Unlike packages.config, only the direct dependencies are listed and the project file does not directly reference any assets (DLL files, content files) out of packages. On restore, NuGet figures out the dependency graph by evaluating the direct and transitive dependencies, makes sure all packages are downloaded into the user's global package cache (not solution-local so it is only downloaded once) and write an assets file into the obj folder that contains a list of all packages and assets that the project uses, as well as additional MSBuild targets if any package contains build logic that needs to be added to a project. So a NuGet restore may download packages if they are not already in the global cache and create this assets file. In addition to package references, the project can also reference CLI tools, which are NuGet packages containing additional commands that will be available for the dotnet in the project directory.

The msbuild-integrated restore only works for PackageReference type projects (.NET Standard, .NET Core by default, but it is opt-in for any .NET project) and not for packages.config projects. If you use a new version of nuget.exe(e.g. 4.3.0), it is able to restore both project types.

Your error about missing types is a bit more interesting: The "reference assemblies" (libraries that are passed as input to the compiler) are not installed on the system but come via NuGet packages. So as long as the NuGet packages are missing from the global package cache or the obj/project.assets.json file has not been generated by a restore operation, fundamental types like System.Objectwill not be available to the compiler.

Solution 2 - .Net

I had similar problems with a .NET Core 2 project that would build just fine on my workstation - both within Visual Studio 2017 and using MSBuild only - but did not build in TeamCity. The error message was:

C:\Program Files\dotnet\sdk\2.1.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.PackageDependencyResolution.targets(327, 5):
Assets file 'D:\TeamCity\buildAgent\work\596486b1d4e7a8e7\Source\Integrations\SomeAPI\obj\project.assets.json' not found.
Run a NuGet package restore to generate this file.

In my build configuration I already had a NuGet install step before the build step:

  • NuGetversion: 3.4.4
  • Restore Mode: Install

It turned out I had to use:

  • NuGet version: 4.0.0 or higher
  • Restore Mode: Restore (Requires NuGet 2.7+)

Solution 3 - .Net

nuget restore will ensure all of your NuGet dependencies are downloaded and available to your project. Whereas dotnet restore is a complete restoration of all NuGet dependencies as well as references and project specific tools. Meaning that if you run nuget restore, you are only restoring NuGet packages.

According to docs.microsoft.com: Dotnet Restore

> The dotnet restore command uses NuGet to restore dependencies as well as project-specific tools that are specified in the project file...

Solution 4 - .Net

None of them worked for me. At the time of creating a project I have selected the option to enable Razor runtime optimization. This caused the build error. Enabling Razor Runtime optimization

When I have recreated the same project without that option, it worked fine for me.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThomasView Question on Stackoverflow
Solution 1 - .NetMartin UllrichView Answer on Stackoverflow
Solution 2 - .NethsopView Answer on Stackoverflow
Solution 3 - .NetExontoView Answer on Stackoverflow
Solution 4 - .NetdotcoderView Answer on Stackoverflow