Getting Setup With C# 8

If you aren’t sure if you are using C# 8, or you know you aren’t and want to know how to access these features. Read this quick guide on getting setup with .NET Core and C# 8.


With IOT becoming bigger and bigger, it makes sense for C# to add a way to iterate over an IEnumerable in an async way while using the yield keyword to get data as it comes in. For example retrieving data signals from an IOT box, we would want to be receiving data and processing it as it is retrieved, but not in a way that blocks CPU while we wait. This is where IAsyncEnumerable comes in!

But We Already Have Async Enumerable Right?

So a common trap to fall into might be that you want to use a return type of Task<IEnumerable<T>>  and make it async. Something like so :

So if we ran this application, what would be the result? Well nothing would appear for 10 seconds, and then we would see all of our datapoints all at once. It’s not going to be thread blocking, it’s still async, but we don’t get the data as soon as we receive it. It’s less IEnumerable and more like a List<T>.

What we really want, is to be able to use the yield  keyword, to return data as we receive it to be processed immediately.

Using Yield With IAsyncEnumerable

So knowing that we want to use yield , we can actually use the new interface in C# 8 called IAsyncEnumerable<T> . Here’s some code that does just that :

So some pointers about this code :

  • Notice that we await our foreach loop itself rather than awaiting the FetchIOTData method call within the foreach loop.
  • We are returning a type of IAsyncEnumerable<T> and not IEnumerable<T>

Other than that, the code should be rather straight forward.

When we run this, instead of 10 seconds of nothing and then all data dumped on us, we get each piece of data as it comes. Ontop of this, the call is still not blocking.

Early Adopters Bonus

If you are using this in late 2018 or early 2019, you’re probably going to have fun trying to get all of this to compile. Common compile errors include :

As detailed in this Github issue coreclr repo, there is a mismatch between the compiler and the library.  You can get around this by copy and pasting this code block into your project until everything is back in sync again.

There is even another issue where iteration will stop early (Wow!). It looks like it will be fixed in Preview 2. I couldn’t replicate this in my particular scenarios, but just know that it might happen.

Both of these issues maybe point to it being early days and not quite anything but proof of concept yet.

I’m calling it now, 2019 is going to be the year of action! .NET Core Tutorials has been running strong for over 2 years now (We were there right from the project.json days). Back then, people were fine reading all about the latest features of .NET Core. But these days, people want to be shown. Live! That’s why I’m starting live coding sessions on every Wednesday and Sunday. I’ll be covering a variety of topics, but you’ll often catch me doing live blog writing sessions where you can get a sneak peak of content before it goes live and ask any questions while I’m doing live coding. We’ve already had some great questions in chat while doing our post on C# 8 IAsyncEnumerable.

So get amongst it. Head on over, drop a follow, and tune in next time!

But enough about me, I want it to be a year of action for you too. That’s why I’m giving away a copy of *any* of Manning’s classic “In Action” books. You know, those ones with the ye olde covers. Like this Core In Action book by Andrew Lock (Who is a great author by the way!).

I bold the word *any* above because it’s not just Core In Action, but actually any “In Action” book you want. Want to learn Redux in 2019? Try Redux In Action. Want to learn all about Amazon Web Services? Try AWS In Action. How about learning a bit of data science in R? Well… You guessed it, try R In Action. Infact just head over to Amazon and check out any of the In Action titles and start drooling over which one you want if you win!

Use any of the entry options below (or multiple), and you are in to win! It’s that easy!

Enter Now

Getting Setup With C# 8

If you aren’t sure if you are using C# 8, or you know you aren’t and want to know how to access these features. Read this quick guide on getting setup with .NET Core and C# 8.

Have You Seen Ranges Yet?

The Index struct is pretty similar to ranges which also made it into C#. If you haven’t already, go check out the article on Ranges in C# 8 here.

It’s not a pre-requisite to know ranges before you use the new Index type, but it’s probably a pretty good primer and they share the new “hat” ^ character.


If you wanted to get the last item of an array, you would typically see code like this :

If you wanted second to last you would end up doing something like :

If you have a List<T>, you would have a couple of different options, mostly involving Linq. So something like this :

But with arrays, what we notice is that we are still always counting from the front. So we are passing in that we want index 2, not that we want the last index persay.

With C# 8 however, we have the ability to do this :

So we can pass in the “hat” character, and this signifies that we are looking for the index X away from the end of the array. You’ll also notice something very important. Whereas junior developers have struggled since the dawn of time to wrap their head around arrays starting at index “0”. When we use the hat character, we are saying we want to count from the end but inclusive. So saying ^1 means the last index, not the second to last index. Weird I know.

And that’s the new index character in a nutshell!

Index As A Type

When you say ^1, you are actually creating a new struct in C# 8. That struct being Index. For example :

All of these create a new struct of Index that hold a value of the last index item.

You might want to use it in this way if you have a particular count from the end that you want to re-use on multiple arrays.

Index Is Simple

The index type is actually really simple. If you take a look at the source code, you’ll see really all it is, is an integer value held inside a struct wrapper.

Getting Setup With C# 8

If you aren’t sure if you are using C# 8, or you know you aren’t and want to know how to access these features. Read this quick guide on getting setup with .NET Core and C# 8.

Current State Of Play

So first off.. Nullable reference types? But.. We’ve been taught for the past 17 years that a big part of “reference” types is that they are nullable. That’s obviously a simplification, but a junior programmer would typically tell you that “value type” => Not Nullable and “reference type” => Nullable.

Infact we have syntax to tell us whether a value type can actually be nullable, for example :

And remember this syntax isn’t just for primitive value types. For example this works just as well :

But now we want to have a piece of syntax to say that this should be a compile time error (Or warning)? Interesting.


So the first question to ask is. Why do we need this? Consider a program like so :

Fairly simple. Notably I’ve left a comment to illustrate that maybe this program is a lot bigger than shown here, but everything should run fine and dandy. Now let’s say after some time, another developer comes along and does something like so  :

It may seem silly at first, but I’ve seen it happen. Someone has come along and set myClass to null to satisfy something they are working on. It’s buried deep in the program, and maybe within their tests, everything looks good.

But at some point, maybe with the perfect storm of conditions, we are going to throw a dreaded NullReferenceException. Naturally, we are going to do something like this and wrap our method call in a null check :

But if I’m the original developer I may say to myself… I never intended this thing to ever be null. But it would be fruitless to say that I never want anything to be set to null. Ever. We would probably break that rule on day 1. But at the same time, are we expecting to code so defensively that we do a null check everytime we use a reference type?

And this is the crux of the nullable reference type. It’s about signally intent in code. I want to specifically say “I expect this to be nullable at some point” or vice versa so that other developers, future myself included, don’t fall into a null reference trap.

Turning On Nullable Reference Types

As noted above, the first thing is that you need to be using C# 8 to turn on the Nullable Reference Types feature. Once that’s done, you need to add a single line to your project’s csproj file :

And that’s it!

Warnings To Expect

Once we’ve turned on the feature, let’s look at a simple piece of code to illustrate what’s going on.

Building this we get two Warnings. I put that in bold because they are Warnings and not compile errors. Your project will still build and run, but it’s just going to warn you about shooting yourself in the foot. The first warning is for us trying to assign null to a variable that isn’t explicitly set to allow nulls.

And the second warning is when we are trying to actually use the non-nullable type and the compiler thinks it’s going to be null.

So both of these aren’t going to stop our application from running (yet, more on that later), but it is going to warn us we could be in trouble.

Let’s instead change our variable to be nullable. I was actually a little worried that the syntax would be reversed. And instead of adding something extra to say something is nullable, I thought they might try and say all reference types are nullable by default, but you can now wrap it in something like  NotNullable<MyClass> myClass... . But thankfully, we are using the same syntax we use to mark a value type as nullable :

Interestingly, if we try and compile this, we still get the  Possible dereference  warning! So now it’s not just about hey this thing is not supposed to be nullable, but you are assigning null, but it’s proactively warning us that hey, you aren’t actually checking if this thing is null and it very well could be. To get rid of it, we need to wrap our stock standard null check.

And just like that, our warnings disappear.

Compiler Warning Limits

The thing is, reference types can be passed around between methods, classes, even entire assemblies. So when throwing up the warnings, it’s not foolproof. For example if we have code that looks like :

We do get a warning that we are assigning null. But we don’t get the Possible Dereference warning. This we can assume that once the object is passed outside the method, whatever happens outside there (Like setting null), we aren’t going to be warned about. But if we assign null so blatantly in the same block of code/method, and then try and use it, then the compiler will try and give us a helping hand.

For comparisons sake, this does generate a warning :

So it’s not just about whether it’s certain, but just whether it’s atleast possible within the current code block.

Nullable Reference Types On Hard Mode

Not happy with just a warning. Well you can always level up and try nullable reference types on hard mode! Simply add the following to your project’s csproj file :

Note that this will treat *all* warnings as errors, not just ones regarding null reference issues. But it means your project will no longer compile if there are warnings being thrown up!

Final Note

There is so much in here to like, I thought I would just riff off a few bullet points about how I feel about the change.

  • This reminds me so much of the In Keyword that was introduced in C# 7.2. That had a few performance benefits, but actually the main thing was about showing the “intent” of the developer. We have a similar thing here.
  • Even if you aren’t quite sure on the feature, it’s almost worth banging it on and checking which  Possible dereference  warnings get thrown up on an existing project. It’s a one line change that can easily be toggled on and off.
  • I like the fact it’s warnings and not errors. It makes it so transitioning a project to use it isn’t some mammoth task. If you are OK with warnings showing up over the course of a month while you work through them ofcourse!
  • There was rumblings of this feature being on by default when you start a new project in C#. That didn’t happen this release, but it could happen in the future. So it’s worth atleast understanding how things work because you very well may end up on a project in the future that uses it.

What do you think? Drop a comment below and let me know!

Getting Setup With C# 8

If you aren’t sure if you are using C# 8, or you know you aren’t and want to know how to access these features. Read this quick guide on getting setup with .NET Core and C# 8.

Introduction To Ranges

Let’s first just show some code and from there, we can iterate on it trying a few different things.

Our starting code looks like :

So essentially we are looking to go from “index” 1 – 3 in our list and output the item. Unsurprisingly when we run this code we get

But let’s say we don’t want to use a for loop, and instead we want to use this new fandangle thing called “ranges”. We could re-write our code like :

And when we run it?

Uh oh… We have one less item than we thought. We’ve ran into our first gotcha when using Ranges. The start of a range is inclusive, but the end of a range is exclusive.

If we change our code to :

Then we get the expected result.

Shortcut Ranges

Using Ranges where it’s “From this index to this index” are pretty handy. But what about “From this index to the end”. Well Ranges have you covered!

From An Index (Inclusive) To The End (Inclusive)

Output :

From The Start (Inclusive) To An Index (Exclusive)

Output :

Entire Range (Inclusive)

Output :

From Index (Inclusive) To X From The End (Inclusive)

This one deserves a quick description. Essentially we have a new operator ^  that is now used to designate “From the end”. I labelled this one as “Inclusive” but it really depends on how you think about “from the end”. In my mind in a list of 5 items ^1  would refer to the 4th item. So if that’s included in the result, it’s inclusive.

Output :

Range As A Type

When we write 1..4, it looks like we are dealing a couple of integers in a new special format, but actually this is almost the initialisation syntax for a range. Similar how we might use {“1”, “2”, “3”} to illustrate us creating an array or list.

We can actually rip out the range from here, and create a new type to be passed around.

This could be handy to pass around into a method or re-use multiple times. I think it’s pretty close to using something like the System.Drawing.Point  object to specify X and Y values rather than having two separate values passed around.

A New Substring

One pretty handy thing about ranges is that they can be used as a faster way to do String.Substring operations. For example :

Would output 234 . Obviously this would be a slight shift in thinking because string.Substring isn’t “From this index to this Index” but instead “From this index count this many characters”.

Who Uses Arrays Anyway? What About List<T>?

So when I first had a play with this. I couldn’t work out what I was doing wrong… As it turns out. It was because I was using a List<T>  instead of an Array. I don’t to be too presumptuous but I would say the majority of times you see a “list” or “set” or data in a business application, it’s going to be of type List<T> . And well.. It’s not available to use Ranges. I also can’t see any talk of it being made either (Possibly because of the linked list nature of List<T> Apparently List<T> is not a linkedlist at all! So then I’m not sure why Ranges are not available). Drop a comment below on your thoughts!

I’ve previously done posts on how to setup both .NET Core 2.1 and .NET Core 2.2. The reason for these posts was because it was still a little shaky exactly which version of the SDK you needed to actually build for these platforms. e.x. If you had .NET Core SDK 2.1, it didn’t actually mean you could build .NET Core 2.1 projects (How infuriating is that?!).

But things have gotten better and now it’s usually just a matter of installing the latest SDK and away you go, so there isn’t really much I could normally write for each version bump. However! .NET Core 3 includes a couple of really important updates that I want to talk about in the future. Windows Forms/WPF development on top of .NET Core, and C# 8. Because of this, I wanted to have a post all written up on setting up your machine for .NET Core 3 development while things are in preview so I don’t have to repeat myself every future post!

Installing the .NET Core 3 Preview SDK

Installing the .NET Core 3 SDK is fairly straight forward. Just head to the download page and grab the SDK (Not the runtime) and install! You do want to ensure you are on the .NET Core 3 page and not the general download page of .NET Core as the current “live” version is 2.2 not 3.

Once installed, you should be able to open a command prompt and run  dotnet --info with the output being something close to :

Of course as long as the version is 3+, you should be good to go.

It’s also important to note that your default SDK on your machine will now be 3 and not 2.2 (Or the previous version you had installed). If you have existing projects that are using this SDK version, you will need to create a new global.json file to be able to run different SDK’s side by side. Luckily there is a great guide on how to do this right here!

Using VS Code

If you like programming in VS Code, then you’re actually good to write .NET Core 3 code right from the get go (Since it’s just a text editor). Obviously you will want to install the “C#” extension if you want all the good intellisense (Including for C# 8 new types), but other than that because builds are all from the command line there isn’t too much to it.

If you want to use C# 8 features in VS Code, see that section of this article below (It’s the same for Visual Studio or VS Code).

Using Visual Studio

A preview version of .NET Core also has a preview version of Visual Studio to accompany it. This can be a little annoying because it’s not just jumping on the “preview” update track for your existing Visual Studio installation, you actually need to download and install a completely new version of Visual Studio. This means another ~6GB of space taken up with a VS version you may use once or twice to try out new features.

I feel the need to point this out because it caught me out initially. The first version of Visual Studio to support .NET Core 3.0 is Visual Studio 2019 Preview 1. Emphasise on the 2019 part because I was wondering why my 2017 preview Visual Studio wasn’t working at first!

You can grab the preview version of Visual Studio here :

I have actually dabbled with a solo installation of the preview version only and not bothered with the current release version. Theoretically it could have a few more bugs in it than the current supported release, but so far so good!

Enabling C# 8 Features

We can enable C# 8 on a project by project basis by editing our .csproj files. Simply open up your project file, and add the following anywhere within your <Project> node :

And that’s literally it (Too easy!).

Some people get trapped thinking that the following will enable C# 8 features :

But remember, version 8 of the language is in preview too. Latest refers to the latest minor version that has actually been released (So at this time, 7.3). If you try and use new features of C# 8, for example the “Range” type, you will get an error like so :

error CS8370: Feature ‘range operator’ is not available in C# 7.3. Please use language version 8.0 or greater.

But other than that, everything is pretty straight forward! Now go ahead and start using Range, AsyncEnumerable, Indices and Nullable Reference Types!

This is part 5 of a series on getting up and running with Azure WebJobs in .NET Core. If you are just joining us, it’s highly recommended you start back on Part 1 as there’s probably some pretty important stuff you’ve missed on the way.

Azure WebJobs In .NET Core

Part 1 – Initial Setup/Zip Deploy
Part 2 – App Configuration and Dependency Injection
Part 3 – Deploying Within A Web Project and Publish Profiles
Part 4 – Scheduled WebJobs
Part 5 – Azure WebJobs SDK

Where Are We Up To?

Thus far, we’ve mostly been playing around with what amounts to a console app and running it in Azure. If anything it’s just been a tidy environment for running little utilities that we don’t want to spin up a whole VM for. But if you’ve used WebJobs using the full .NET Framework before, you know there are actually libraries to get even more out of Web Jobs. Previously this wasn’t available for .NET Core applications, until now!

Installing The WebJob Packages

Go ahead and create stock standard .NET Core console application for us to test things out on.

The first thing we need to do with our new app is install a nuget package from Microsoft that opens up quite a few possibilities.

Note that this needs to be atleast version 3.0.0. At the time of writing this is version 3.0.2 so you shouldn’t have any issues, but just incase you are trying to migrate an old project.

Now something that changed from version 2.X to 3.X of the library is that you now need to reference a second library called “Microsoft.Azure.WebJobs.Extensions”. This is actually pretty infuriating because no where in any documentation does it talk about this. There is this “helpful” message on the official docs :

The instructions tell how to create a WebJobs SDK version 2.x project. The latest version of the WebJobs SDK is 3.x, but it is currently in preview and this article doesn’t have instructions for that version yet.

So it was only through trial and error did I actually get things up and running. So you will want to run :

I honestly have no idea what exactly you could do without this as it seemed like literally every single trigger/webjob function I tried would not work without this library. But alas.

Building Our Minimal Timer WebJob

I just want to stress how different version 3.X of WebJobs is to 2.X. It feels almost like a complete rework, and if you are trying to come from an older version, you may think some of this looks totally funky (And that’s because it is a bit). But just try it out and have a play and see what you think.

First thing we want to do is create a class that holds some of our WebJob logic. My code looks like the following :

So a couple of notes :

  • The Singleton attribute just says that there should only ever be one of this particular WebJob method running at any one time. e.g. If I scale out, it should still only have one instance running.
  • The “TimerTrigger” defines how often this should be run. In my case, once a minute.
  • Then I’m just writing out the current time to see that we are running.

In our Main method of our console application, we want to add a new Host builder object and start our WebJob. The code for that looks like so :

If you’ve used WebJobs before, you’re probably used to using the JobHostConfiguration  class to do all your configuration. That’s now gone and replaced with the HostBuilder . Chaining is all the rage these days in the .NET Core world so it looks like WebJobs have been given the same treatment.

Now you’ll notice that I’ve added a a call to the chain called AddAzureStorageCoreServices()  which probably looks a little weird given we aren’t using anything with Azure at all right? We are just trying to run a hello world on a timer. Well Microsoft says bollox to that and you must use Azure Blob Storage to store logs and a few other things. You see when you use Singleton (Or just in general what you are doing needs to run on a single instance), it uses Azure Blob Storage to create a lock so no other instance can run. It’s smart, but also sort of annoying if you really don’t care and want to throw something up fast. It’s why I always walk people through creating a Web Job *without* this library, because it starts adding a whole heap of things on top that just confuse what you are trying to do.

Anyway, you will need to create an appsettings.json file in the root of your project (Ensure it’s set to Copy Always to your output directory). It should contain (atleast) the following :

For the sake of people banging their heads against the wall with this and searching Google. Here’s something to help them.

If you are getting the following error :

Unhandled Exception: System.InvalidOperationException: Unable to resolve service for type ‘Microsoft.Azure.WebJobs.DistributedLockManagerContainerProvider’ while attempting to activate ‘Microsoft.Azure.WebJobs.Extensions.Timers.StorageScheduleMonitor’.

This means that you haven’t added the call to AddAzureStorageCoreServices()

If you are instead getting the following error :

Unhandled Exception: Microsoft.Azure.WebJobs.Host.Listeners.FunctionListenerException: The listener for function ‘SayHelloWebJob.TimerTick’ was unable to start. —> System.ArgumentNullException: Value cannot be null.
Parameter name: connectionString
at Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(String connectionString)

This means that you did add the call to add the services, but it can’t find the appsetting for the connection strings. First check that you have them formatted correctly in your appsettings file, then ensure that your appsettings is actually being output to your publish directory correctly.

Moving on!

In the root of our project, we want to create a run.cmd  file to kick off our WebJob. We went over this in Part 1 of this series, so if you need a reminder feel free to go back.

I’m just going to go ahead and Publish/Zip my project up to Azure (Again, this was covered in Part 1 incase you need help!). And what do you know!

Taking This Further

At this point, so much of this new way of doing WebJobs is simply trial and error. I had to guess and bumble my way through so much just to get to this point. As I talked about earlier, the documentation is way behind this version of the library which is actually pretty damn annoying. Especially when the current release on Nuget is version 3.X, and yet there is no documentation to back it up.

One super handy tool I used was to look at the Github Repo for the Azure Webjobs SDK. Most notably, there is a sample application that you can go and pick pieces of out of to get you moving along.

What’s Next?

To be honest, this was always going to be my final post in this series. Once you reach this point, you should already be pretty knowledgeable about WebJobs, and through the SDK, you can just super power anything you are working on.

But watch this space! I may just throw out a helpful tips post in the future of all the other annoying things I found about the SDK and things I wished I had known sooner!

I came across an interesting problem while developing a monitoring tool recently. It was a simple HTTP check to see if a webpage had a certain piece of text on it. When it didn’t, I was saving the HTML and I had to sift through it at a later date to try and work out what went wrong. At some point, reading HTML (Or loading the HTML without any CSS/JS) become really tiresome so what I really wanted was the ability to take a screenshot of a webpage and save it as an image.

Boy. What a ride that took me on. After hours of searching, It felt like I had two options. Either I could use a dedicated paid library to save HTML to Image, or I could use many HTML to Image command line utilities – I would just have to invoke it from C# code. Neither really appealed a hell of a lot.

While explaining the problem to a friend, the conversation went a bit like this :

Friend : Do you need to manipulate the page in any way? Like click a link or something?
Me : No I just need to do a get request for a page and save the result, that’s it. 
Friend : Oh OK. I was going to say, you could use the Selenium part for clicking around the page if you needed it. Anyway, good luck!

It took a few seconds to register but… Of course… Selenium can take screenshots of webpages! After all it’s just browser automation anyway! Admittedly it’s kinda heavy for just taking screenshots, but for my nice little utility I really didn’t care. And actually the ability to extend the code to be able to then *do* things on the page at a later date probably only makes it more of an attractive option.

Installing Selenium Into Your Project

We’re going to need two packages. The first is mandatory and that is the Selenium.Support package. Run the following from your package manager command line :

Next we want to install the driver for the browser we want to use. So this is going to totally depend on which browser you want to do the browsing. For me I want to use Chrome, but you can also choose to use Firefox or PhantomJS etc so modify the following command for what you need.

Our Selenium Screenshot Code

First I’ll give you the code, then we can talk it through.

Taking it step by step, it’s actually really easy (Almost too easy).

  • Our options with Headless tells chrome that we don’t want to actually see the chrome window. Mostly because it’s annoying having it pop up all the time, but headless also sometimes causes problems with screenshots (More on this later).
  • We create our ChomeDriver with a very specific path, this is because without it, we get this weird error which again, I’ll talk about shortly.
  • Navigate to the page we want
  • Take a screenshot
  • Save it down as a file (We can also get a byte array at this point if we want to instead push it to cloud storage etc).

And that’s literally it. You can now take screenshots of webpages! But now onto the edge cases.

Unable To Find ChromeDriver Exception

So initially I had the following exception :

The chromedriver.exe file does not exist in the current directory or in a directory on the PATH environment variable.

It turned out to be a two pronged fix.

The first is that we need to make sure we have installed the actual ChromeDriver nuget package *and* rebuilt our solution completely. The nuget package command is :

This is actually a little confusing because the ChromeDriver class is available in code, intellisense and all, but it won’t run unless you install that package.

Next for some reason it couldn’t find the ChromeDriver.exe in my applications bin folder still. What seemed to fix it was the fact you can give it a bit of a nudge in the right direction, and so telling it to look in the current application folder (e.g. the Bin folder) got us there.

Screenshot Is Off Screen

While testing this out I noticed that when I swapped to using the headless chrome browser, that sometimes what I wanted to view was just off screen.  While there was actually some nifty libraries to take just a screenshot of a single element in Selenium, I had a cruder (but simpler) solution!

If we can just make the window a reasonable width, but really long, then we can take a screenshot of the “browser window”, and it should capture everything. Obviously this isn’t an exact science and if the length of your page is forever changing, this may not work. But if it’s static content, just a little longer, this works perfectly.

The code looks a bit like :

So now as long as our content is no longer than 2000px long (In my case, it will never be), then we are set. Again, there’s probably more elegant solutions but this works so well for what I need it to do.

Recently while upgrading a couple of projects to .NET Core 2.2, I came across this error.

A quick google revealed that actually people had the same issue when their projects were going from 2.0 to 2.1 too. And all the fixes seemed kinda flaky and typically involved “Try this and pray” type steps.

To be honest, I know how to fix diagnose and fix the issue, but I don’t really know why that particular error message is the one that comes up.

First thing I noticed is that this error will only ever happen when you’ve tried opening a project in Visual Studio and tried to build. In some cases I’ve been able to build using the dotnet CLI, but not inside Visual Studio. If after building in Visual Studio, I then try and build from the dotnet CLI tool, I then start getting this error too. However if I delete the bin folder and rebuild from the CLI, we are all clear.

Next, in all cases the version of .NET Core I want to target is not available and not selected for my project inside VS. So if I right click my project and view properties, the Target Framework is blank :

This is because the version of Visual Studio that I’m using doesn’t actually support the version of .NET Core I am trying to run. It’s sort of this weird situation where even if you have the correct .NET Core SDK installed, that really only sets you up for using the dotnet CLI and writing code in something like VSCode.

All you need to do is update Visual Studio. Let me put that in big bold letters so people coming from Google can get their answer fast :

You Need To Update Visual Studio

Hopefully that’s clear enough!

Even once you update Visual Studio, you will likely need to delete the bin and obj folders of your project and then rebuild again from VS. Now there may be one very edge case that this doesn’t resolve your issues. And that’s if you are using the very latest preview builds for .NET Core SDK that Visual Studio either doesn’t support yet, or only supports in the Pre-Release version of VS. Rare, but it does happen.

There is some pretty nifty stuff making it’s way into .NET Core 2.2 such as a new route “dispatcher” and inbuilt support for healthchecks. But you’re going to need to set up your workstation (And your project) to handle .NET Core 2.2 first! In previous articles where we’ve updated from 2.0 to 2.1, it’s been a right headache, but slowly Microsoft are getting better at handling this whole version bump thing.

If You Want Preview – Use The Command Line

Just to kick us off, I need to point out that in almost all cases, if you are intending to use the preview SDK’s for .NET Core. You are going to need to be creating, building, and publishing projects from the command line. There is support for Visual Studio for preview SDK’s in some cases, but even opening a preview project in the wrong version of Visual Studio can completely break the project by dumping junk in the bin folder etc.

So again, try and do all of the following without Visual Studio atleast so you know it works. Then you can deal with the headache of Visual Studio!

Installing The .NET Core 2.2 SDK

So remember that there is really two parts to .NET Core. There is the SDK which is how your project is built, and the runtime which is what your application actually runs on.

Let’s first sort out the SDK part of this equation.

We want to go to specifically the .NET Core 2.2 download page and download the latest SDK (Not runtime) for our operating system. Note that this isn’t the general .NET Core download page, the current LTS version of .NET Core is currently 2.1. So that’s the version that gets thrust upon you. You specifically need to skip that, go direct to the 2.2 download page, and install the latest SDK.

After installing, open a command prompt and run the following :

This tells us what it thinks the latest (Or to be more correct, the default) version of the .NET Core SDK we are running.

In this example, I’m currently running version 2.2.100-preview3, which is the latest at the time of writing. Anything 2.2.*** should be fine. It’s also interesting to note that this is a big departure from .NET Core 2.1, where you could have version 2.1.*** of the SDK, and it actually couldn’t build 2.1 projects… So it’s nice Microsoft have tidied that up.

Now if you create a new project using the command line, by default it’s going to be using 2.2 as it’s SDK, but if you want to modify an existing project to use the latest build tools (And remember, the SDK is different to the runtime as we will see later), then you need to modify your global.json.

In the root of your project, you should either already have a global.json or create a new one. The contents of which should look like :

Where the version should match your SDK you just installed.

Without a global.json, you will actually use the default anyway. But it’s good to try and be explicit with what version of the SDK you know everything builds fine with. This is especially true if later you install a new version of the SDK with breaking changes, and all your old projects “automatically” update and break.

Updating A Project Runtime To .NET Core 2.2

Changing the project runtime is actually super easy. Just open up your csproj and bump up your TargetFramework.

Go ahead and build your project using dotnet build  from the command line, and all going well you should be good to go.

If you see an error such as :

Then you currently aren’t running on the latest SDK. Either you have not installed the latest SDK or your global.json in the project/solution folder is pointing to an older version.

Visual Studio Support

.NET Core 2.2 does have support inside Visual Studio but only from version 15.9 Preview 3 onwards. At the time of writing, this means you need to download the pre-release version of Visual Studio here to get access to that specific version.

The installation itself is some 5GB, so unless you really need the full development experience for preview SDK’s, you should probably try and go without!

If you are able to upgrade non pre-release version of Visual Studio to atleast 15.9, then you should be able to open .NET Core 2.2 projects.