.NET 8 is the latest and greatest version of the .NET platform, which is a free, cross-platform, open-source developer platform for building many different types of applications. .NET 8 was released November 14, 2023, and will be supported for three years as a long-term support (LTS) release.

Novanet, together with NNUG, held a release party, to celebrate this new version. We had the pleasure of being joined by Filip Ekberg. He shared a lot of insights, regarding what new features .NET 8 and C# 12 can offer. A lot of people showed up to the meetup, so it seems there's a big interest in the new developments.

In this blog post, I will share some of the insights Filip Ekberg shared about .NET 8 and some of the key features that I look forward to using in my projects.

If you are interested in learning more about .NET 8 and how it can help you create amazing applications, then read on! 😊

Filip Ekberg presenting some of the new features of .NET 8

News in .NET 8

One of the topics Filip talked a lot about was the performance improvements that occur in .NET 8. There has been a lot of work put in to make .NET 8 perform better. By utilizing some of the new features, we can now write near allocation-free code, which means the applications can be extremely performant. This is also something that is utilized internally, so you get the benefits just by upgrading.


This time around, one of the System.Text.Json has gotten a lot of improvements regarding serialization. With .NET 8, Microsoft is bridging the gap between Newtonsoft.Json and System.Text.Json even more, which is quite beneficial.

Amongst the key things is that there will be support for serializing interface hierarchies, new naming policies, and read-only properties. Also, you will now be allowed to disable the reflection-based serializer by default. This will be very useful in native AOT apps, making sure that the apps are as trimmed as possible.

Time abstraction

With .NET 8, the new TimeProvider and ITimer interface adds new time abstraction functionality. This allows us to mock time in test scenarios. With this, you are able to retrieve local and UTC time, obtain a timestamp for performance, and create a timer.

Data validation

System.ComponentModel.DataAnnotations will include new data validation attributes. These are intended for cloud-native services. Previously, the typical validators were aimed at UI-data entry validation, but the new attributes are aimed towards non-user-entry data, such as configuration options.

The following list shows new attributes and properties that have been added:

  • RangeAttribute.MinimumIsExclusive / RangeAttribute.MaximumIsExclusive - Specifies whether bounds are included in the allowable range
  • System.ComponentModel.DataAnnotations.LengthAttribute - specifies lower and upper bounds for strings or collections ([Length(5, 10] —> requires at least 5 and at most 10 elements in a collection)
  • System.ComponentModel.DataAnnotations.Base64StringAttribute - Validates that a string is valid Base64
  • System.ComponentModel.DataAnnotations.AllowedValuesAttribute/DeniedValuesAttribute - Specifies allow and deny lists

Other things worth mentioning

There are a lot more that’s new in .NET 8. A few, I find worth mentioning, without going into great detail, are the new stream-based ZipFile methods and metrics.

System.Diagnostics.Metrics now provides APIs for attaching key-value pair tags to metric objects. These can be used to monitor the health and performance of an application.

By using the new overload of ZipFile.CreateFromDirectory, you are now able to collect all files in a directory and store them in a zip file into a provided stream. This means that you avoid using disk storage as a temporary storage device in between steps, which is good when disk space is limited.

News in C# 12

In addition to .NET 8, C# as a language has been updated. The new version is C# 12, and one of the key thing, mentioned by Filip Ekberg, is the introduction of collection expressions together with the spread operator. This means that there is a simplified way to create arrays.

int[] foo = [1,2,3];

Span bar = [4,5,6];

This also makes it even easier to write multidimensional arrays:

int[][] fooBar = [[1,2,3], [4,5,6], [7,8,9]];

The spread operator will replace the arguments it is applied to with its elements. This makes it possible to merge collections together.

int[] foo = [1,2,3];
List bar = [4,5,6];
Span fooBar = [7,8,9];

Collection combined = [..foo, ..bar, ..fooBar];

Another key feature, which is probably the main highlight of C# 12, is the addition of primary constructors to classes. This has been a feature available for records for a while but is now also available for classes. There is a difference, in that they do not generate any public properties. The following snippet shows how one can use primary constructors in a controller.

public class HelloWorldController(IHelloWorldService service) : ControllerBase
   public ActionResult Get()
      return service.HelloWord();


There's also a lot of great news for ASP.NET Core, and specifically for Blazor. One of the key features that is now introduced, is the ability to combine Blazor Server and Blazor WebAssembly hosting models. This means that interactive client rendering can start by using Blazor Server, and continue with WebAssembly once the Blazor bundle has been downloaded. This new hosting model is called "Interactive Auto", and it is said that this is the fastest app startup experience. In addition, this allows you to choose between Blazor Server and WebAssembly for interactivity on a per-component basis.

Because of this change, a new project template has been introduced. This is called the "Blazor Web App" template. In doing this, the Blazor Server template has been removed, and ASP.NET Core Hosted option has been removed from the Blazor WebAssembly template. These scenarios can be configured in the new template.

Another cool upgrade in Blazor is enhanced navigation and form handling. Usually, navigating between pages or submitting forms in static server rendered sites triggers a full page refresh. Now, Blazor can intercept requests and perform fetch requests, which then patches the response into the DOM. This allows you to preserve the page state, and in turn makes the page load faster and smoother. Enhanced navigation is enabled by default, while enhanced form handling can be enabled for specific forms.


In this post, we got to see what Filip Ekberg thinks are some key features of .NET 8 and C# 12. We looked at a few features that I also think are worth mentioning. The performance improvements themselves make it worth considering an upgrade. At last, we took a quick look at new features in the new version of Blazor.

There is a lot more to discover, so I urge you to read the official documentation from Microsoft about news in .NET8, C# 12, ASP.NET Core and Blazor.

If you would like a high level overview of the features, the following PDF contains the files used by Filip Ekberg in his presentation. I highly recommend reading through to get a feeling of the new features, before deciding on what you want to take closer look at.