.NET 6 Preview 5 is now available and includes many great new improvements to ASP.NET Core.
Here’s what’s new in this preview release:
- .NET Hot Reload updates for
dotnet watch
- ASP.NET Core SPA templates updated to Angular 11 and React 17
- Use Razor syntax in SVG
foreignObject
elements - Specify null for
Action
andRenderFragment
component parameters - Reduced Blazor WebAssembly download size with runtime relinking
- Configurable buffer threshold before writing to disk in Json.NET output formatter
- Subcategories for better filtering of Kestrel logs
- Faster get and set for HTTP headers
- Configurable unconsumed incoming buffer size for IIS
Get started
To get started with ASP.NET Core in .NET 6 Preview 5, install the .NET 6 SDK.
If you’re on Windows using Visual Studio, we recommend installing the latest preview of Visual Studio 2019 16.11. Visual Studio 2022 Preview 1 is also releasing today and .NET 6 Preview 5 is included in that release. If you’re on macOS, we recommend installing the latest preview of Visual Studio 2019 for Mac 8.10.
To get setup with .NET MAUI & Blazor for cross-platform native apps, see the latest instructions in the .NET MAUI getting started guide. Be sure to also check out the Announcing .NET MAUI Preview 5 blog post for all the details on what’s new in .NET MAUI in this release.
Note: .NET MAUI is not yet supported in Visual Studio 2022 Preview 1. For .NET MAUI development, please use the latest preview of Visual Studio 2019 16.11 instead.
To install the latest .NET WebAssembly tools for ahead-of-time (AOT) compilation and runtime relinking, run the following command from an elevated command prompt:
dotnet workload install microsoft-net-sdk-blazorwebassembly-aot
If you’ve installed the .NET WebAssembly workload previously, you can update it to .NET 6 Preview 5 by running the following command from an elevated command prompt:
dotnet workload update
Note: There is a known issue with installing optional SDK workloads using the .NET 6 Preview 5 SDK included with Visual Studio 2022 Preview 1. To workaround this issue, install the .NET 6 Preview 5 SDK from https://dot.net/get-dotnet6 after installing Visual Studio 2022 Preview 1.
Upgrade an existing project
To upgrade an existing ASP.NET Core app from .NET 6 Preview 4 to .NET 6 Preview 5:
- Update all Microsoft.AspNetCore.* package references to
6.0.0-preview.5.*
. - Update all Microsoft.Extensions.* package references to
6.0.0-preview.5.*
.
To upgrade a .NET MAUI Blazor app from .NET 6 Preview 4 to .NET 6 Preview 5 we recommend starting from a new .NET MAUI Blazor project created with the .NET 6 Preview 5 SDK and then copying code over from your original project.
See the full list of breaking changes in ASP.NET Core for .NET 6.
.NET Hot Reload updates for dotnet watch
We’ve been working on various improvements to .NET Hot Reload for .NET 6. Some of these improvements are available in .NET 6 Preview 5, while others are still a work in progress and will be refined in future preview updates.
You no longer need to specify hotReloadProfile
in launchSettings.json to use .NET Hot Reload with dotnet watch
. .NET Hot Reload with project appropriate behavior is now enabled by default.
When a code edit is made that cannot be hot reloaded (a “rude” edit), dotnet watch
will now ask if you want to restart the app to apply the change:
watch : Unable to apply hot reload because of a rude edit. Rebuilding the app...
watch : Unable to handle changes to C:\Users\daroth\Desktop\BlazorApp\Pages\Index.razor.
watch : Do you want to restart your app - Yes (y) / No (n) / Always (a) / Never (v)?
These options have the following behaviors:
- Choosing Yes will restart the app.
- Choosing No won’t restart the app and will leave the app running without the changes applied.
- Choosing Always will restart the app as needed when changes cannot be hot reloaded.
- Choosing Never won’t restart the app and avoids future prompts.
You can always manually restart the app using Ctrl+R.
Note: There is a known issue in this release that selecting Always still continues to prompt for future rude edits. This will get addressed in a future preview release.
To disable support for .NET Hot Reload when using dotnet watch
, use the --no-hot-reload
command-line option.
.NET Hot Reload with dotnet watch
will also now correctly detect rude edits Blazor WebAssembly apps. Changes applied to Blazor WebAssembly apps will get reapplied to the app when the browser is refreshed or the app is loaded in a separate browser tab or browser instance.
ASP.NET Core SPA templates updated to Angular 11 and React 17
The ASP.NET Core single-page app (SPA) templates for Angular and React have been updated to Angular 11 and React 17. We also expect to further update the Angular template to Angular 12 in a future .NET 6 preview release now that it’s been released.
Support Razor syntax in SVG foreignObject
elements
You can now use Razor syntax, including the use of Blazor components, in SVG foreignObject
elements:
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" rx="10" ry="10" width="200" height="200" stroke="black" fill="none" />
<foreignObject x="20" y="20" width="160" height="160">
<p>@message</p>
</foreignObject>
</svg>
@code {
string message = "Wow, it's so nice that this text wraps like it's HTML...because that's what it is!";
}
We also did a bunch of verification and testing to make sure that Blazor has good support for SVG scenarios. We think Blazor’s SVG support is now in good shape. If you hit any issues using SVG in Blazor with this release, please let us know by creating issues on GitHub.
Specify null for Action
and RenderFragment
component parameters
You can now specify null
for the value of Blazor component parameters of type Action
and RenderFragment
, which simplifies the authoring of components that take optional callback parameters or template parameters.
Reduced Blazor WebAssembly download size with runtime relinking
One of the largest parts of a default Blazor WebAssembly app is the WebAssembly based .NET runtime (dotnet.wasm) that the app carries with it. Blazor WebAssembly already has support for trimming unused code from the .NET core framework libraries. However, the download size of the runtime has been constant.
Not all of the runtime logic is needed by every app. For example, a large part of the runtime logic and related data files are for globalization scenarios. This globalization support enables Blazor WebAssembly apps to handle strings, numbers, dates, etc. based on the current culture. But for apps that don’t need this functionality, all that data and logic is just extra bits.
.NET apps that don’t need globalization functionality can opt out of it and use invariant globalization instead by setting the InvariantGlobalization
property to true
in their project files. In .NET 5, this would allow a Blazor WebAssembly app to avoid downloading globalization data, but the related logic in the .NET runtime would still be included.
In .NET 6 Preview 5, you can now use the .NET WebAssembly tools (the same tools used for .NET WebAssembly AOT compilation) to relink the runtime to remove unneeded logic and dramatically reduce the size of the runtime. If you have the .NET WebAssembly workload installed, runtime relinking is done automatically when you publish the app. The size reduction is particularly dramatic when using invariant globalization mode.
If you haven’t already, you can install the .NET WebAssembly tools by running the following command from an elevated command prompt:
dotnet workload install microsoft-net-sdk-blazorwebassembly-aot
The following table shows the transfer size of dotnet.wasm for a default Blazor WebAssembly project with .NET 5 and .NET 6:
dotnet.wasm | Transfer size (kB) |
---|---|
.NET 5 default | 884 |
.NET 6 default | 780 |
.NET 6 relinked | 756 |
.NET 6 invariant mode | 393 |
Configurable buffer threshold before writing to disk in Json.NET output formatter
The Newtonsoft.Json
output formatter by default buffers responses up to 32 KiB in memory before buffering to disk. This is to avoid performing synchronous IO, which can result in other side-effects such as thread starvation and application deadlocks. However, if your response if was larger than 32 KiB this resulted in a lot of avoidable disk I/O. You can now configure the memory threshold before buffering to disk.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages()
.AddNewtonsoftJson(options =>
{
options.OutputFormatterMemoryBufferThreshold = 48 * 1024;
});
}
Note: We still recommend using the
System.Text.Json
output formatter unless you require theNewtonsoft.Json
serializer for compatibility reasons. TheSystem.Text.Json
serializer is fully async and will work efficiently for any size payload.
Subcategories for better filtering of Kestrel logs
Prior to this change, enabling verbose logging for Kestrel was prohibitively expensive as all of Kestrel shared the same logging category name (Microsoft.AspNetCore.Server.Kestrel
). We’ve now split up that category into multiple new subcategories:
Microsoft.AspNetCore.Server.Kestrel
(current category): ApplicationError, ConnectionHeadResponseBodyWrite, ApplicationNeverCompleted, RequestBodyStart, RequestBodyDone, RequestBodyNotEntirelyRead, RequestBodyDrainTimedOut, ResponseMinimumDataRateNotSatisfied, InvalidResponseHeaderRemoved, HeartbeatSlow.Microsoft.AspNetCore.Server.Kestrel.BadRequests
: ConnectionBadRequest, RequestProcessingError, RequestBodyMinimumDataRateNotSatisfied.Microsoft.AspNetCore.Server.Kestrel.Connections
: ConnectionAccepted, ConnectionStart, ConnectionStop, ConnectionPause, ConnectionResume, ConnectionKeepAlive, ConnectionRejected, ConnectionDisconnect, NotAllConnectionsClosedGracefully, NotAllConnectionsAborted, ApplicationAbortedConnection.Microsoft.AspNetCore.Server.Kestrel.Http2
: Http2ConnectionError, Http2ConnectionClosing, Http2ConnectionClosed, Http2StreamError, Http2StreamResetAbort, HPackDecodingError, HPackEncodingError, Http2FrameReceived, Http2FrameSending, Http2MaxConcurrentStreamsReached.Microsoft.AspNetCore.Server.Kestrel.Http3
: Http3ConnectionError, Http3ConnectionClosing, Http3ConnectionClosed, Http3StreamAbort, Http3FrameReceived, Http3FrameSending.
While your existing rules will continue to work (log filtering applies rules with the longest matching category prefix), you can now be more selective on which rules you enable. For example, the observability overhead of enabling Debug
logging for just bad requests is greatly reduced and can be achieved with the following configuration:
{
"Logging": {
"LogLevel": {
"Microsoft.AspNetCore.Kestrel.BadRequests": "Debug"
}
}
}
Faster get and set for HTTP headers
We added new API to expose all common headers available on System.Net.Http.HeaderNames
as properties on the Microsoft.AspNetCore.Http.IHeaderDictionary
resulting in an easier to use API. For example, the in-line middleware below gets/sets both request and response headers using the new APIs:
app.Use(async (context, next) =>
{
var hostHeader = context.Request.Headers.Host;
app.Logger.LogInformation("Host header: {host}", hostHeader);
context.Response.Headers.XPoweredBy = "ASP.NET Core 6.0-preview5";
await next.Invoke(context);
var dateHeader = context.Response.Headers.Date;
app.Logger.LogInformation("Response date: {date}", dateHeader);
});
For implemented headers the get
/set
accessors are implemented by going directly to the field and bypassing the lookup. For non-implemented headers, the accessors can bypass the initial lookup against implemented headers and directly perform the Dictionary<string, StringValues>
lookup. This results in faster access for both scenarios.
Method | Branch | Type | Mean | Op/s | Delta |
---|---|---|---|---|---|
GetHeaders | preview4 | Plaintext | 25.793 ns | 38,770,569.6 | – |
GetHeaders | preview5 | Plaintext | 12.775 ns | 78,279,480.0 | +101.9% |
GetHeaders | preview4 | Common | 121.355 ns | 8,240,299.3 | – |
GetHeaders | preview5 | Common | 37.598 ns | 26,597,474.6 | +222.8% |
GetHeaders | preview4 | Unknown | 366.456 ns | 2,728,840.7 | – |
GetHeaders | preview5 | Unknown | 223.472 ns | 4,474,824.0 | +64.0% |
SetHeaders | preview4 | Plaintext | 49.324 ns | 20,273,931.8 | – |
SetHeaders | preview5 | Plaintext | 34.996 ns | 28,574,778.8 | +40.9% |
SetHeaders | preview4 | Common | 635.060 ns | 1,574,654.3 | – |
SetHeaders | preview5 | Common | 108.041 ns | 9,255,723.7 | +487.7% |
SetHeaders | preview4 | Unknown | 1,439.945 ns | 694,470.8 | – |
SetHeaders | preview5 | Unknown | 517.067 ns | 1,933,985.7 | +178.4% |
Configurable unconsumed incoming buffer size for IIS
Prior to this change, the IIS server only buffered 64 KiB of unconsumed request bodies. This resulted in reads being constrained to that maximum size, which impacts the performance when large incoming bodies such as large uploads. In .NET 6 Preview 5, we’ve changed the default buffer size from 64 KiB to 1 MiB which should result in improved throughput for large uploads. In our tests, a 700 MiB upload that used to take 9 seconds now only takes 2.5 seconds.
The downside of a larger buffer size is an increased per-request memory consumption when the app isn’t quickly reading from the request body. So, in addition to changing the default buffer size, we’ve also made the buffer size configurable, allowing you to tune it based on your workload.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<IISServerOptions>(
options =>
{
options.MaxRequestBodySize = 64 * 1024;
}
);
}
Give feedback
We hope you enjoy this preview release of ASP.NET Core in .NET 6. We’re eager to hear about your experiences with this release. Let us know what you think by filing issues on GitHub.
Thanks for trying out ASP.NET Core!
The post ASP.NET Core updates in .NET 6 Preview 5 appeared first on ASP.NET Blog.
Comments
Post a Comment