.Net Core 2.0: project.assets.json’ doesn’t have a target for ‘.NETStandard,Version=v2.0’

The Problem

Odd error when building a .net core project with Visual Studio Code. This built a few weeks ago – went back it it and I’m getting this

C:\Program Files\dotnet\sdk\2.0.0\Sdks\Microsoft.NET.Sdk\build\Microsoft.PackageDependencyResolution.targets(165,5): error : Assets file ‘myproject\obj\project.assets.json’ doesn’t have a target for ‘.NETStandard,Version=v2.0’. Ensure that restore has run and that you have included ‘netstandard2.0’ in the TargetFrameworks for your project. [myproject\MyProject.csproj]

.Net Core has been installed, it used to work and there is not much on the Internet. Bafflement.

Solution

Turns out the bin and obj folders for each of the project need to be manually deleted. Once done then the command

gave me the green light and normal service has been resumed. No idea what it going on but sorted now – so I thought I would take a minute and post the solution to my small corner of the Internet. Cheers.

Multiple Projects with .Net Core and Visual Studio Code

The challenge is to create a solution in VS Code with multiple projects. There are three projects

  1. A console application
  2. A web api application
  3. A library with data access code that is common to both.

It will look like this when we are finished

Expanded to show detail

We need a solution that can build out all these projects in one click. Since we using VS Code and enjoying it’s lightweightness we’ll be relying completely on the new .Net Core Command Line Interface. I enjoy a challenge so using the command line seems fun (to me). Let’s go.

(TL;DR;)

In case you don’t want to read the detail – the commands used to set up all projects, solutions and references are

From project root

Preliminary

To do this you’ll need VS Code’s C# extension installed into visual studio. Go to extensions and search for C#.

Install and away you go.

Note on command line

All .Net Core CLI commands can be entered into the terminal window in VS Code or into the standard command prompt if you prefer. Navigate to the root folder and enter your first command

Create Console Application

This installs our console application project. Since we are on .Net Core 2.0 we get the csproj file rather than the json project file of earlier versions. This installs the console app in a new folder with the same name as it’s containing folder. If we want a different name to the folder we do that by

But we don’t want that. We are keeping it simple. What I like about .Net Core is that it’s had all the gubbins stripped out. So our proj file for the console app is simply …

Nice. I understand that.

Create Common Library

Next we want to create a C# dll to host some common code like data access.

Creates an empty project called Demo.Common with a nice simple proj file thus

Link Common Library to Console app

Change to the console app direct and run the add reference common

Inserts the following into the console proj file

So the console app can access code in the common project and the two will build out together.

Add Nuget package to Common Library

We commonly want to add some nuget packages to our projects. So lets add the HtmlAgility pack and a C# driver for MongoDB – no reason for them other than I often use them.

Change directories back to common library

Now add the packages

Look at the proj file and you can see the package references inserted

VS Code likes to tell me to restore the project I.e. run dotnet restore. You don’t need to. Dotnet build or dotnet run does it for you.

Build Console Application

Let’s check things are working as they should and build our console app.

Output

  Demo.Common -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Common\bin\Debug\netstandard2.0\Demo.Common.dll

Demo.ConsoleApp -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.ConsoleApp\bin\Debug\netcoreapp2.0\Demo.ConsoleApp.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Good – by building the project we get both common and the console application building.

Create API 

Return to root folder

Now add a web api project called Demo.Api

Change to the Api folder

Now add a reference to our common library

The Api proj file looks a bit more complex but I’ll still pretty minimal compared to Visual Studio proj files.

Now let’s build that project. Staying in the Api folder

And the output shows us two projects have been built.

  Demo.Common -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Common\bin\Debug\netstandard2.0\Demo.Common.dll

Demo.Api -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Api\bin\Debug\netcoreapp2.0\Demo.Api.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Joining everything together

Ok , so we want all the projects to build in one click. Because we have two independent applications (an API and a console app) we aren’t going to be able to do the build by navigating to a folder and building the proj file. We need a solution file to bind them all together

(this shamefully baffled me for a while. I was trying all sorts with launch.json etc… The solution is obvious though – embarrassed for not getting it immediately)

Back to root

Now add the solution file. We don’t want it in it’s own directory so omit the -o parameter. Add in the -n otherwise it takes it’s name from the containing folder which we don’t want in this case.

Now include the API and Console app

The solution file now includes the project info

Staying in the solution directory run build

And now all three projects are built.

Demo.Common -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Common\bin\Debug\netstandard2.0\Demo.Common.dll

Demo.ConsoleApp -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.ConsoleApp\bin\Debug\netcoreapp2.0\Demo.ConsoleApp.dll

Demo.Api -> C:\development\Demo\ASP.NET Core\MultipleProjects\Demo.Api\bin\Debug\netcoreapp2.0\Demo.Api.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Finished!!!

Demo code

The rather uninspiring skeleton demo app is at
https://github.com/timbrownls20/Demo/tree/master/ASP.NET%20Core/MultipleProjects

More interesting the same pattern is on a .Net Core API for some Buddhist texts I’ve been working on
https://github.com/timbrownls20/Pali-Canon/tree/master/Api

So

https://github.com/timbrownls20/Pali-Canon/tree/master/Api/PaliCanon.Loader
Is the console app that parses HTML and populates a document database with the texts

https://github.com/timbrownls20/Pali-Canon/tree/master/Api/PaliCanon.Api
Is the web api to access the texts

https://github.com/timbrownls20/Pali-Canon/tree/master/Api/PaliCanon.Common
Is the model and repositories common to both.  It’s the same pattern as the simplified demo app and I’m using VS Code for that – just to try it out really.

Useful Links

https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x
Full documentation for .Net Core Command Line Interface

https://code.visualstudio.com/download
Visual Studio Code is freely available here.

Getting the Root Directory Path for .Net Core Applications

Quick one. Given any .Net app I want to know the root path of the application i.e. the top level directory. I was doing this with .Net Core but it puts in extra directories by default in the exe path i.e.

bin\Debug\netcoreapp2.0\my.dll

so my normal kuldgy methods weren’t working. This all works for any .Net app not just Core in fairness – it’s just that the extra stuffed in by .Net Core threw me a little. There are all kinds of ways to find this for particular applications web, windows etc.. but this should work generally. Well it worked with my little console app anyway.

The Code

Use reflection to targeting the executable and get the path

this will get you

file:///c:/development/MyApp/bin/Debug/netcoreapp2.0/myApp.dll

which is the UNC path. Combine with Path.GetDirectoryName i.e.

this gets

file:\c:\development\MyApp\bin\Debug\netcoreapp2.0

which is a  file path now and it has got us the directory of the executable. It’s still not where we want to be so use some regex

This will chop up the path and gives you

c:\development\MyApp

which is correct.

The Function

So overall a useful function for this could be

Which does what we need or I quite like it as a (much abused) extension method

Which can be called like

Which gives

c:\development\MyApp\TargetFile.cs

Job done.

The Regex

Not everyone likes Regex*. But for the aficionados here is what it is doing

For example matching this

file:\c:\development\MyApp\bin\Debug\netcoreapp2.0

Is my match – this will match a drive and a path up to

It’s a lookahead (zero length assertion). It will check for “bin” but not include it in the match

It’s a negative lookbehind (zero length assertion again). It will make sure that the letters fil don’t immediately proceed the match. This is to stop e:// being the match i.e. the e from file.

Clearly this assumes that the bin folder is directly under the root path as it normal is. If it isn’t in your app then break out your favourite Regex editor and write your own. It will make a man/woman/scared child of you.

(* Hardly anyone likes it – well I haven’t met many)

Useful Links

https://stackoverflow.com/questions/837488/how-can-i-get-the-applications-path-in-a-net-console-application
Full disclosure – the first bit of this is from this SO question. The extension I did with my very own coding fingers

http://regexstorm.net/tester
Regex storm – C# regex tester. Very good. JavaScript based testers don’t work with this as they can’t do negative lookbehinds.

https://www.regular-expressions.info/lookaround.html
Look ahead, behind and all around with zero length assertions