{"id":47488,"date":"2023-09-12T10:11:00","date_gmt":"2023-09-12T17:11:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=47488"},"modified":"2024-12-13T14:18:35","modified_gmt":"2024-12-13T22:18:35","slug":"announcing-dotnet-8-rc1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-8-rc1\/","title":{"rendered":"Announcing .NET 8 Release Candidate 1"},"content":{"rendered":"<p>.NET 8 RC1 is now available. This is our first of two release candidates. This release includes a new AOT mode for both Android and WASM, System.Text.Json improvements, and Azure Managed Identity support for containers. Now is great time to pick up and test .NET 8 if you haven&#8217;t yet. <\/p>\n<p>The dates for <a href=\"https:\/\/dotnetconf.net\/\">.NET Conf 2023<\/a> have been announced! Join us November 14-16, 2023 to celebrate the .NET 8 release!<\/p>\n<p><a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/8.0\">Download .NET 8 RC1<\/a> for Linux, macOS, and Windows.<\/p>\n<ul>\n<li><a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/8.0\">Installers and binaries<\/a><\/li>\n<li><a href=\"https:\/\/hub.docker.com\/_\/microsoft-dotnet-aspnet\/\">Container images<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/core\/tree\/main\/release-notes\/8.0\">Release notes<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/compatibility\/8.0?toc=%2Fdotnet%2Ffundamentals%2Ftoc.json&amp;bc=%2Fdotnet%2Fbreadcrumb%2Ftoc.json\">Breaking changes<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/core\/blob\/main\/release-notes\/8.0\/known-issues.md\">Known issues<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/core\/issues\">GitHub issue tracker<\/a><\/li>\n<\/ul>\n<p>There are several exciting posts you should check out as well:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/asp-net-core-updates-in-dotnet-8-rc-1\">ASP.NET Core Updates in .NET 8 RC1<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-maui-in-dotnet-8-rc-1\">.NET MAUI Updates in .NET 8 RC1<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/vs\/v178P2\">Visual Studio 2022 17.8 Preview 2<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-ef8-rc1\">Entity Framework Updates in .NET 8 RC1<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/whats-new\/dotnet-8\">What&#8217;s New in .NET 8<\/a> describes all the new features in .NET 8. For a broader view of the platform, read <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/why-dotnet\/\">Why .NET?<\/a>.<\/li>\n<\/ul>\n<h2>System.Text.Json Improvements<\/h2>\n<h3><code>System.Net.Http.Json<\/code> extensions  for IAsyncEnumerable<\/h3>\n<p>https:\/\/github.com\/dotnet\/runtime\/pull\/89258<\/p>\n<p>RC1 sees the inclusion of IAsyncEnumerable streaming deserialization extension methods:<\/p>\n<pre><code class=\"language-C#\">const string RequestUri = \"https:\/\/api.contoso.com\/books\";\r\nusing var client = new HttpClient();\r\nIAsyncEnumerable&lt;Book&gt; books = client.GetFromJsonAsAsyncEnumerable&lt;Book&gt;(RequestUri);\r\n\r\nawait foreach (Book book in books)\r\n{\r\n    Console.WriteLine($\"Read book '{book.title}'\");\r\n}\r\n\r\npublic record Book(int id, string title, string author, int publishedYear);<\/code><\/pre>\n<p>Credit to @IEvangelist for contributing the implementation.<\/p>\n<h3><code>JsonContent.Create<\/code> overloads accepting <code>JsonTypeInfo<\/code><\/h3>\n<p>https:\/\/github.com\/dotnet\/runtime\/pull\/89614<\/p>\n<p>It is now possible to create <code>JsonContent<\/code> instances using trim safe\/source generated contracts:<\/p>\n<pre><code class=\"language-C#\">var book = new Book(id: 42, \"Title\", \"Author\", publishedYear: 2023);\r\nHttpContent content = JsonContent.Create(book, MyContext.Default.Book);\r\n\r\npublic record Book(int id, string title, string author, int publishedYear);\r\n\r\n[JsonSerializable(typeof(Book))]\r\npublic partial class MyContext : JsonSerializerContext \r\n{ }<\/code><\/pre>\n<p>Credit to @brantburnett for contributing the implementation.<\/p>\n<h3><code>JsonNode.ParseAsync<\/code> APIs<\/h3>\n<p>https:\/\/github.com\/dotnet\/runtime\/pull\/90006<\/p>\n<p>Adds support for parsing <code>JsonNode<\/code> instances from streams:<\/p>\n<pre><code class=\"language-C#\">using var stream = File.OpenRead(\"myFile.json\");\r\nJsonNode node = await JsonNode.ParseAsync(stream);<\/code><\/pre>\n<p>Credit to @DoctorKrolic for contributing the implementation.<\/p>\n<h3><code>JsonSerializerOptions.MakeReadOnly(bool populateMissingResolver)<\/code><\/h3>\n<p>https:\/\/github.com\/dotnet\/runtime\/pull\/90013<\/p>\n<p>The existing parameterless <code>JsonSerializerOptions.MakeReadOnly()<\/code> method was designed to be trim-safe and will therefore throw an exception in cases where the options instance hasn&#8217;t been configured with a resolver.<\/p>\n<p>Calling the new overload with<\/p>\n<pre><code class=\"language-C#\">options.MakeReadOnly(populateMissingResolver: true);<\/code><\/pre>\n<p>will populate the options instance with the default reflection resolver if one is missing. This emulates the initialisation logic employed by the <code>JsonSerializer<\/code> methods that accept <code>JsonSerializerOptions<\/code>. A side-effect of that behavior is that the new overload is marked <code>RequiresUnreferenceCode<\/code>\/<code>RequiresDynamicCode<\/code> and is therefore unsuitable for Native AOT applications.<\/p>\n<h2><code>AndroidStripILAfterAOT<\/code> mode on Android<\/h2>\n<p>https:\/\/github.com\/xamarin\/xamarin-android\/pull\/8172<\/p>\n<p>We try to choose the best the default configuration for .NET and .NET MAUI applications out of the box. In .NET 6 and higher, specifically, these applications now utilize profiled ahead-of-time (AOT) compilation mode by default when they are built in <code>Release<\/code> mode. AOT compilation results in faster startup time and runtime performance improvements at the expense of a larger app size. Profiled AOT, only AOT compiles a portion of your application&#8217;s startup path &#8212; improving startup time, with a minimal increase to application size. The new <code>AndroidStripILAfterAOT<\/code> setting removes unused IL that was AOT-compiled, reducing the apk size by at least 0 &#8211; 3.5% for a dotnet template application.<\/p>\n<h3>When to consider using <code>AndroidStripILAfterAOT<\/code>:<\/h3>\n<p>If performance is more of a concern for your Android application than app size, AOT-compiling all code is a great way to achieve the best startup and runtime performance. <code>$(AndroidStripILAfterAOT)<\/code> goes a step further to remove the unused IL, making the app size increase from AOT-compilation more reasonable. The removed IL will also no longer be present, making it more difficult (but not impossible) to reverse engineer your application&#8217;s .NET code.<\/p>\n<h3>How to use <code>AndroidStripILAfterAOT<\/code>:<\/h3>\n<p>Set the following MsBuild property for your Android app:<\/p>\n<pre><code class=\"language-xml\">&lt;PropertyGroup Condition=\" '$(Configuration)' == 'Release' \"&gt;\r\n  &lt;AndroidStripILAfterAOT&gt;true&lt;\/AndroidStripILAfterAOT&gt;\r\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<p>By default setting <code>AndroidStripILAfterAOT<\/code> to true will <em>override<\/em> the default <code>AndroidEnableProfiledAot<\/code> setting, allowing all trimmable AOT&#8217;d methods to be removed.  Profiled AOT and IL stripping can be used together by explicitly setting both:<\/p>\n<pre><code class=\"language-xml\">&lt;PropertyGroup Condition=\" '$(Configuration)' == 'Release' \"&gt;\r\n  &lt;AndroidStripILAfterAOT&gt;true&lt;\/AndroidStripILAfterAOT&gt;\r\n  &lt;AndroidEnableProfiledAot&gt;true&lt;\/AndroidEnableProfiledAot&gt;\r\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<p><code>.apk<\/code> size results for a <code>dotnet new android<\/code> app:<\/p>\n<table>\n<thead>\n<tr>\n<th><code>$(AndroidStripILAfterAOT)<\/code><\/th>\n<th><code>$(AndroidEnableProfiledAot)<\/code><\/th>\n<th><code>.apk<\/code> size<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>true<\/td>\n<td>true<\/td>\n<td>7.7MB<\/td>\n<\/tr>\n<tr>\n<td>false<\/td>\n<td>true<\/td>\n<td>7.7MB<\/td>\n<\/tr>\n<tr>\n<td>true<\/td>\n<td>false<\/td>\n<td>8.1MB<\/td>\n<\/tr>\n<tr>\n<td>false<\/td>\n<td>false<\/td>\n<td>8.4MB<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Note that <code>$(AndroidStripILAfterAOT)<\/code>=false and <code>$(AndroidEnableProfiledAot)<\/code>=true is the <em>default<\/em> Release configuration environment, for 7.7MB.<\/p>\n<h3>Limitations:<\/h3>\n<p>Not all of the AOT-compiled methods are able to be removed. At runtime, there are various scenarios where we have to switch from AOT to JIT to produce the correct result. With that said, we will be continuously working on reducing gaps in the upcoming .NET 9 release.<\/p>\n<h3>Final note<\/h3>\n<p>We would like to invite everyone to try out this new feature and file any discovered issues to help us improve the user experience further. Issues can be filed directly to <a href=\"https:\/\/github.com\/dotnet\/runtime\">dotnet\/runtime repository<\/a>.<\/p>\n<h2>Configuration Binding Generator breaking change<\/h2>\n<p>The <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-8-preview-6\/\">configuration binding generator<\/a> has switched to using the compiler interceptors preview feature to emit binding logic &#8211; https:\/\/github.com\/dotnet\/runtime\/pull\/90835.<\/p>\n<p>In non Web SDK scenarios (i.e. apps that require a <code>Microsoft.Extensions.Configuration.Binder<\/code> package reference for binding, like console apps), the following additional MSBuild property is now required to enable the generator:<\/p>\n<pre><code class=\"language-diff\">&lt;PropertyGroup&gt;\r\n  &lt;EnableConfigurationBindingGenerator&gt;true&lt;\/EnableConfigurationBindingGenerator&gt;\r\n+ &lt;Features&gt;$(Features);InterceptorsPreview&lt;\/Features&gt;\r\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<p>This is temporary. In RC-2, enabling the generator will switch back to only requiring the one gesture. The compiler inceptors feature will be enabled implicitly in a reliable way.<\/p>\n<pre><code class=\"language-diff\">&lt;PropertyGroup&gt;\r\n  &lt;EnableConfigurationBindingGenerator&gt;true&lt;\/EnableConfigurationBindingGenerator&gt;\r\n- &lt;Features&gt;$(Features);InterceptorsPreview&lt;\/Features&gt;\r\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<h2>Containers switch to non-preview tagging pattern<\/h2>\n<p>Issue: https:\/\/github.com\/dotnet\/dotnet-docker\/issues\/4772\nPR: https:\/\/github.com\/dotnet\/dotnet-docker\/pull\/4817<\/p>\n<p>In preparation for the GA release of .NET 8, the .NET container images have switched to a new tagging pattern for RC 1 that removes &#8220;preview&#8221; from the tag name.<\/p>\n<p>In previous preview releases of .NET 8, floating tags were published with the name of <code>8.0-preview<\/code> and <code>8.0-preview-&lt;OS&gt;<\/code>. These will no longer be maintained starting with the RC 1 release. Instead, you should migrate your tag references to <code>8.0<\/code> or <code>8.0-&lt;OS&gt;<\/code>. Making this change will allow for a seamless transition upon the GA release of .NET 8 as these will be the permanent tags that will be maintained throughout the lifetime of .NET 8.<\/p>\n<h2>Cross-building Windows apps with Win32 resources on non-Windows<\/h2>\n<p>Issue: https:\/\/github.com\/dotnet\/runtime\/issues\/3828\nPR: https:\/\/github.com\/dotnet\/runtime\/pull\/89303<\/p>\n<p>Many thanks to <a href=\"https:\/\/github.com\/anatawa12\">@anatawa12<\/a> for this great contribution!<\/p>\n<p>When building applications targeting Windows on non-Windows platforms, the resulting executable is now updated with any specified Win32 resources &#8211; for example, application icon, manifest, version information.<\/p>\n<p>Previously, applications had to be built on Windows in order to have such resources. Fixing this gap in cross-building support has been a popular request, as it was a significant pain point affecting both infrastructure complexity and resource usage.<\/p>\n<h2>SDK: Container publishing now supports Azure Managed Identity<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/dotnet\/sdk-container-builds\/issues\/425\">Azure Container Registry auth failure when using Managed Identity<\/a><\/li>\n<\/ul>\n<p>The SDK Container publish feature is an easy way to <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/docker\/publish-as-container\">package .NET applications into containers<\/a> and push them to container registries like Docker Hub, Azure Container Registry, or other popular registries. Pushing to these remote registries often requires authentication, which is usually handled by the <code>docker login<\/code> command. Some registries, like Azure Container Registry, don&#8217;t use a standard username\/password setup and instead rely on an OAuth token exchange. The SDK Container publishing tools didn&#8217;t know how to handle this token exchange, and so users that used Managed Identity on Azure Container Registry (or used any other registry that used Identity Token exchange) would encounter authentication errors when pushing their containers. With .NET 8.0.100 RC1 we&#8217;re happy to announce that we now support the OAuth token exchange authentication method, so ACR and all other registries that use it now just work. A typical publishing flow might now look like:<\/p>\n<pre><code class=\"language-shell\">&gt; az acr login -n &lt;your registry name&gt;\r\n&gt; dotnet publish -r linux-x64 -p PublishProfile=DefaultContainer<\/code><\/pre>\n<p>Doesn&#8217;t get much simpler than that! You can learn more about registry authentication in <a href=\"https:\/\/github.com\/dotnet\/sdk-container-builds\/blob\/main\/docs\/RegistryAuthentication.md\">our docs<\/a>, and you learn how to <a href=\"https:\/\/github.com\/dotnet\/sdk-container-builds\/blob\/main\/docs\/GettingStarted.md\">get started containerizing your apps as well<\/a>.<\/p>\n<h2><code>WasmStripILAfterAOT<\/code> mode on WASM<\/h2>\n<p>https:\/\/github.com\/dotnet\/runtime\/pull\/88926<\/p>\n<p>Blazor WebAssembly and WASM Browser support ahead-of-time (AOT) compilation, where you can compile your .NET code directly into WebAssembly. AOT compilation results in runtime performance improvements at the expense of a larger app size. This new stripping mode reduces the size of _framework folder by 1.7% &#8211; 4.2%, based on the testing we&#8217;ve done mentioned in the above github issue.<\/p>\n<h3>When to consider using <code>WasmStripILAfterAOT<\/code>:<\/h3>\n<p>This feature is ideal any time you enable AOT compilation, so give it a try for a smaller application!<\/p>\n<h3>How to use <code>WasmStripILAfterAOT<\/code>:<\/h3>\n<p>Set the following MsBuild property for your Blazor WebAssembly or WASM Browser app:<\/p>\n<pre><code class=\"language-c#\">&lt;PropertyGroup&gt;\r\n  &lt;RunAOTCompilation&gt;true&lt;\/RunAOTCompilation&gt;\r\n  &lt;WasmStripILAfterAOT&gt;true&lt;\/WasmStripILAfterAOT&gt;\r\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<p>It will trim away the IL code for most of the compiled methods, including methods from the libraries and the ones authored by the app developers.<\/p>\n<h3>Limitations:<\/h3>\n<p>Not all of the compiled methods are trimmable. At runtime, there are various scenarios where we have to switch from AOT to interpreter to produce the correct result. With that said, we will be continuously working on reducing the gap in the upcoming .NET9 release.<\/p>\n<h3>Final note<\/h3>\n<p>We would like to invite everyone to try out this new feature and file any discovered issues to help us improve the user experience further. Issues can be filed directly to <a href=\"https:\/\/github.com\/dotnet\/runtime\">dotnet\/runtime repository<\/a>.<\/p>\n<h2>WPF Hardware Acceleration in RDP<\/h2>\n<p>https:\/\/github.com\/dotnet\/wpf\/pull\/7684<\/p>\n<p>In the past, all WPF applications accessed remotely had to use software rendering, even if the system had hardware rendering capabilities. We have added a new option that enables application developers to opt-in for hardware acceleration for RDP by utilizing an AppContext switch. <\/p>\n<p>Hardware acceleration refers to the use of a computer&#8217;s graphics processing unit (GPU) to speed up the rendering of graphics and visual effects in an application. This can result in improved performance and more seamless, responsive graphics. In contrast, software rendering relies solely on the computer&#8217;s central processing unit (CPU) to render graphics, which can be slower and less effective.<\/p>\n<h3>How to enable Hardware Acceleration in RDP for WPF app?<\/h3>\n<p>We offer two methods for enabling hardware acceleration in RDP:<\/p>\n<ol>\n<li>By adding the <code>RuntimeHostConfigurationOption<\/code> in the <code>*.csproj<\/code> file, as demonstrated below:<\/li>\n<\/ol>\n<pre><code class=\"language-xml\">&lt;ItemGroup&gt;\r\n      &lt;RuntimeHostConfigurationOption Include=\"Switch.System.Windows.Media.EnableHardwareAccelerationInRdp\" Value=\"true\" \/&gt;\r\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<ol start=\"2\">\n<li>By adding the <code>configProperty<\/code> in the <code>*.runtimeconfig.json<\/code> file, as shown below:<\/li>\n<\/ol>\n<pre><code class=\"language-json\"> \"configProperties\": {\r\n      \"Switch.System.Windows.Media.EnableHardwareAccelerationInRdp\": true\r\n    } <\/code><\/pre>\n<h3>Final note<\/h3>\n<p>We would like to invite everyone to try out this new feature and file any discovered issues to help us improve the user experience further. Issues can be filed directly to <a href=\"https:\/\/github.com\/dotnet\/wpf\">dotnet\/wpf repository<\/a>.<\/p>\n<h2>Community Contributor<\/h2>\n<p>This month&#8217;s community contributer is Jakub Majocha.  Here&#8217;s a little about him in his own words:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2023\/09\/community-spotlight.png\" width=\"250px\" \/><\/p>\n<p><em>I&#8217;m Jakub Majocha. I live in Cracow, Poland where I work in a field unrelated to software. I have a lifelong interest in computer programming but my experience is limited to small one-off scripts, some tools for in-house use and solving programming puzzles like Advent Of Code. I like to chill tinkering with code and I have found F# perfect for this.<\/em><\/p>\n<p><em>The fact that I could just jump in and contribute to F# shows how accommodating the community is. It&#8217;s also thanks to the language itself. F#, with its type inference, concise syntax and low ceremony, allows for quick experimentation, refactoring and trying things out. It&#8217;s just fun and relaxing.<\/em><\/p>\n<h2>Summary<\/h2>\n<p>The team has transitioned to working on quality and polish as we near the final release in November. Now is a great time to report any issues that you&#8217;ve noticed in RC1 and earlier builds. We&#8217;d also love to hear your reactions to using these features.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>.NET 8 RC1 is now available with improvements to System.Text.Json, a new AOT mode for Android and WASM, Azure Managed Identity support for containers, and more!<\/p>\n","protected":false},"author":651,"featured_media":47956,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[7701],"class_list":["post-47488","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","tag-dotnet-8"],"acf":[],"blog_post_summary":"<p>.NET 8 RC1 is now available with improvements to System.Text.Json, a new AOT mode for Android and WASM, Azure Managed Identity support for containers, and more!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/47488","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/651"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=47488"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/47488\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/47956"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=47488"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=47488"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=47488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}