.NET Core 3.0 Preview 8 is now available and it includes a bunch of new updates to ASP.NET Core and Blazor.
Here’s the list of what’s new in this preview:
- Project template updates
- Cleaned up top-level templates in Visual Studio
- Angular template updated to Angular 8
- Blazor templates renamed and simplified
- Razor Class Library template replaces the Blazor Class Library template
- Case-sensitive component binding
- Improved reconnection logic for Blazor Server apps
NavLink
component updated to handle additional attributes- Culture aware data binding
- Razor Pages support for
@attribute
- New networking primitives for non-HTTP Servers
- Unix domain socket support for the Kestrel Sockets transport
- gRPC support for CallCredentials
- ServiceReference tooling in Visual Studio
- Diagnostics improvements for gRPC
Please see the release notes for additional details and known issues.
Get started
To get started with ASP.NET Core in .NET Core 3.0 Preview 8 install the .NET Core 3.0 Preview 8 SDK
If you’re on Windows using Visual Studio, install the latest preview of Visual Studio 2019.
.NET Core 3.0 Preview 8 requires Visual Studio 2019 16.3 Preview 2 or later
To install the latest Blazor WebAssembly template also run the following command:
dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.0.0-preview8.19405.7
Upgrade an existing project
To upgrade an existing an ASP.NET Core app to .NET Core 3.0 Preview 8, follow the migrations steps in the ASP.NET Core docs.
Please also see the full list of breaking changes in ASP.NET Core 3.0.
To upgrade an existing ASP.NET Core 3.0 Preview 7 project to Preview 8:
- Update Microsoft.AspNetCore.* package references to 3.0.0-preview8.19405.7.
- Update package references to Microsoft.AspNetCore.Components.Browser to instead reference Microsoft.AspNetCore.Components.Web.
- In Razor components rename
OnInit
toOnInitialized
andOnInitAsync
toOnInitializedAsync
. - In Blazor apps, update Razor component parameters to be public, as non-public component parameters now result in an error.
- In Blazor WebAssembly apps that make use of the
HttpClient
JSON helpers, add a package reference to Microsoft.AspNetCore.Blazor.HttpClient. - On Blazor form components remove use of
Id
andClass
parameters and instead use the HTMLid
andclass
attributes. - Rename
ElementRef
toElementReference
. - Remove backing field declarations when using
@ref
or specify the@ref:suppressField
parameter to suppress automatic backing field generation. - Update calls to
ComponentBase.Invoke
to callComponentBase.InvokeAsync
. - Update uses of
ParameterCollection
to useParameterView
. - Update uses of
IComponent.Configure
to useIComponent.Attach
. - Remove use of namespace
Microsoft.AspNetCore.Components.Layouts
.
You should hopefully now be all set to use .NET Core 3.0 Preview 8.
Project template updates
Cleaned up top-level templates in Visual Studio
Top level ASP.NET Core project templates in the “Create a new project” dialog in Visual Studio no longer appear duplicated in the “Create a new ASP.NET Core web application” dialog. The following ASP.NET Core templates now only appear in the “Create a new project” dialog:
- Razor Class Library
- Blazor App
- Worker Service
- gRPC Service
Angular template updated to Angular 8
The Angular template for ASP.NET Core 3.0 has now been updated to use Angular 8.
Blazor templates renamed and simplified
We’ve updated the Blazor templates to use a consistent naming style and to simplify the number of templates:
- The “Blazor (server-side)” template is now called “Blazor Server App”. Use
blazorserver
to create a Blazor Server app from the command-line. - The “Blazor” template is now called “Blazor WebAssembly App”. Use
blazorwasm
to create a Blazor WebAssembly app from the command-line. - To create an ASP.NET Core hosted Blazor WebAssembly app, select the “ASP.NET Core hosted” option in Visual Studio, or pass the
--hosted
on the command-line
dotnet new blazorwasm --hosted
Razor Class Library template replaces the Blazor Class Library template
The Razor Class Library template is now setup for Razor component development by default and the Blazor Class Library template has been removed. New Razor Class Library projects target .NET Standard so they can be used from both Blazor Server and Blazor WebAssembly apps. To create a new Razor Class Library template that targets .NET Core and supports Pages and Views instead, select the “Support pages and views” option in Visual Studio, or pass the --support-pages-and-views
option on the command-line.
dotnet new razorclasslib --support-pages-and-views
Case-sensitive component binding
Components in .razor files are now case-sensitive. This enables some useful new scenarios and improves diagnostics from the Razor compiler.
For example, the Counter
has a button for incrementing the count that is styled as a primary button. What if we wanted a Button
component that is styled as a primary button by default? Creating a component named Button
in previous Blazor releases was problematic because it clashed with the button
HTML element, but now that component matching is case-sensitive we can create our Button
component and use it in Counter
without issue.
Button.razor
<button class="btn btn-primary" @attributes="AdditionalAttributes" @onclick="OnClick">@ChildContent</button>
@code {
[Parameter]
public EventCallback<UIMouseEventArgs> OnClick { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object> AdditionalAttributes { get; set; }
}
Counter.razor
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<Button OnClick="IncrementCount">Click me</Button>
@code {
int currentCount = 0;
void IncrementCount()
{
currentCount++;
}
}
Notice that the Button
component is pascal cased, which is the typical style for .NET types. If we instead try to name our component button
we get a warning that components cannot start with a lowercase letter due to the potential conflicts with HTML elements.
We can move the Button
component into a Razor Class Library so that it can be reused in other projects. We can then reference the Razor Class Library from our web app. The Button
component will now have the default namespace of the Razor Class Library. The Razor compiler will resolve components based on the in scope namespaces. If we try to use our Button
component without adding a using statement for the requisite namespace, we now get a useful error message at build time.
NavLink
component updated to handle additional attributes
The built-in NavLink
component now supports passing through additional attributes to the rendered anchor tag. Previously NavLink
had specific support for the href
and class
attributes, but now you can specify any additional attribute you’d like. For example, you can specify the anchor target like this:
<NavLink href="my-page" target="_blank">My page</NavLink>
which would render:
<a href="my-page" target="_blank" rel="noopener noreferrer">My page</a>
Improved reconnection logic for Blazor Server apps
Blazor Server apps require a live connection to the server in order to function. If the connection or the server-side state associated with it is lost, then the the client will be unable to function. Blazor Server apps will attempt to reconnect to the server in the event of an intermittent connection loss and this logic has been made more robust in this release. If the reconnection attempts fail before the network connection can be reestablished, then the user can still attempt to retry the connection manually by clicking the provided “Retry” button.
However, if the server-side state associated with the connect was also lost (e.g. the server was restarted) then clients will still be unable to connect. A common situation where this occurs is during development in Visual Studio. Visual Studio will watch the project for file changes and then rebuild and restart the app as changes occur. When this happens the server-side state associated with any connected clients is lost, so any attempt to reconnect with that state will fail. The only option is to reload the app and establish a new connection.
New in this release, the app will now also suggest that the user reload the browser when the connection is lost and reconnection fails.
Culture aware data binding
Data-binding support (@bind
) for <input>
elements is now culture-aware. Data bound values will be formatted for display and parsed using the current culture as specified by the System.Globalization.CultureInfo.CurrentCulture
property. This means that @bind
will work correctly when the user’s desired culture has been set as the current culture, which is typically done using the ASP.NET Core localization middleware (see Localization).
You can also manually specify the culture to use for data binding using the new @bind:culture
parameter, where the value of the parameter is a CultureInfo
instance. For example, to bind using the invariant culture:
<input @bind="amount" @bind:culture="CultureInfo.InvariantCulture" />
The <input type="number" />
and <input type="date" />
field types will by default use CultureInfo.InvariantCulture
and the formatting rules appropriate for these field types in the browser. These field types cannot contain free-form text and have a look and feel that is controller by the browser.
Other field types with specific formatting requirements include datetime-local
, month
, and week
. These field types are not supported by Blazor at the time of writing because they are not supported by all major browsers.
Data binding now also includes support for binding to DateTime?
, DateTimeOffset
, and DateTimeOffset?
.
Razor Pages support for @attribute
Razor Pages now support the new @attribute
directive for adding attributes to the generate page class.
For example, you can now specify that a page requires authorization like this:
@page
@attribute [Microsoft.AspNetCore.Authorization.Authorize]
<h1>Authorized users only!<h1>
<p>Hello @User.Identity.Name. You are authorized!</p>
New networking primitives for non-HTTP Servers
As part of the effort to decouple the components of Kestrel, we are introducing new networking primitives allowing you to add support for non-HTTP protocols.
You can bind to an endpoint (System.Net.EndPoint
) by calling Bind
on an IConnectionListenerFactory
. This returns a IConnectionListener
which can be used to accept new connections. Calling AcceptAsync
returns a ConnectionContext
with details on the connection. A ConnectionContext
is similar to HttpContext
except it represents a connection instead of an HTTP request and response.
The example below show a simple TCP Echo server hosted in a BackgroundService built using these new primitives.
public class TcpEchoServer : BackgroundService
{
private readonly ILogger<TcpEchoServer> _logger;
private readonly IConnectionListenerFactory _factory;
private IConnectionListener _listener;
public TcpEchoServer(ILogger<TcpEchoServer> logger, IConnectionListenerFactory factory)
{
_logger = logger;
_factory = factory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_listener = await _factory.BindAsync(new IPEndPoint(IPAddress.Loopback, 6000), stoppingToken);
while (true)
{
var connection = await _listener.AcceptAsync(stoppingToken);
// AcceptAsync will return null upon disposing the listener
if (connection == null)
{
break;
}
// In an actual server, ensure all accepted connections are disposed prior to completing
_ = Echo(connection, stoppingToken);
}
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
await _listener.DisposeAsync();
}
private async Task Echo(ConnectionContext connection, CancellationToken stoppingToken)
{
try
{
var input = connection.Transport.Input;
var output = connection.Transport.Output;
await input.CopyToAsync(output, stoppingToken);
}
catch (OperationCanceledException)
{
_logger.LogInformation("Connection {ConnectionId} cancelled due to server shutdown", connection.ConnectionId);
}
catch (Exception e)
{
_logger.LogError(e, "Connection {ConnectionId} threw an exception", connection.ConnectionId);
}
finally
{
await connection.DisposeAsync();
_logger.LogInformation("Connection {ConnectionId} disconnected", connection.ConnectionId);
}
}
}
Unix domain socket support for the Kestrel Sockets transport
We’ve updated the default sockets transport in Kestrel to add support Unix domain sockets (on Linux, macOS, and Windows 10, version 1803 and newer). To bind to a Unix socket, you can call the ListenUnixSocket()
method on KestrelServerOptions
.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.ConfigureKestrel(o =>
{
o.ListenUnixSocket("/var/listen.sock");
})
.UseStartup<Startup>();
});
gRPC support for CallCredentials
In preview8, we’ve added support for CallCredentials
allowing for interoperability with existing libraries like Grpc.Auth
that rely on CallCredentials
.
Diagnostics improvements for gRPC
Support for Activity
The gRPC client and server use Activities to annotate inbound/outbound requests with baggage containing information about the current RPC operation. This information can be accessed by telemetry frameworks for distributed tracing and by logging frameworks.
EventCounters
The newly introduced Grpc.AspNetCore.Server
and Grpc.Net.Client
providers now emit the following event counters:
total-calls
current-calls
calls-failed
calls-deadline-exceeded
messages-sent
messages-received
calls-unimplemented
You can use the dotnet counters
global tool to view the metrics emitted.
dotnet counters monitor -p <PID> Grpc.AspNetCore.Server
ServiceReference tooling in Visual Studio
We’ve added support in Visual Studio that makes it easier to manage references to other Protocol Buffers documents and Open API documents.
When pointed at OpenAPI documents, the ServiceReference experience in Visual Studio can generated typed C#/TypeScript clients using NSwag
.
When pointed at Protocol Buffer (.proto
) files, the ServiceReference experience will Visual Studio can generate gRPC service stubs, gRPC clients, or message types using the Grpc.Tools
package.
SignalR User Survey
We’re interested in how you use SignalR and the Azure SignalR Service, and your opinions on SignalR features. To that end, we’ve created a survey we’d like to invite any SignalR customer to complete. If you’re interested in talking to one of the engineers from the SignalR team about your ideas or feedback, we’ve provided an opportunity to enter your contact information in the survey, but that information is not required. Help us plan the next wave of SignalR features by providing your feedback in the survey.
Give feedback
We hope you enjoy the new features in this preview release of ASP.NET Core and Blazor! Please let us know what you think by filing issues on GitHub.
Thanks for trying out ASP.NET Core and Blazor!
Correction: 8/14/2019
An earlier version of this blog post referenced a productivity feature in Blazor to automatically generate backing fields for elements that utilized the @ref
attribute. Unfortunately, we missed a critical design flaw which prevents this from working end-to-end. For more information check out this announcement.
Followed the instructions above and upgraded Blazor Server app to Preview 8. Keep getting following error:”rzc generate exited with code 2″ in file C:\Program Files\dotnet\sdk\3.0.100-preview8-013656\Sdks\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Microsoft.NET.Sdk.Razor.CodeGeneration.targets. Any ideas?
So slowly this version, so hard choose , many develpors had to shift to other tech group ,
Is there any performance improvements in the recent releases ?
Hi Guys. Has the serialization api in JS Interop changed? Use use to work: https://github.com/aesalazar/AsteroidsWasm/blob/master/Asteroids.BlazorComponents/JsInterop/InteropSounds.cs#L60. The JS would receive an array of strings. Now it only received the first string generated by the List<string> in c#.
Ok, well I fixed it using the spread operator on the function in JavaScript. Seems that a list is now serialized as a a series of arguments so had do do
function(...sounds)
: https://github.com/aesalazar/AsteroidsWasm/blob/blazor_preview8/Asteroids.BlazorComponents/content/JsInteropAsteroidsSound.js#L28Blazor Web Assembly used to work but after upgrading I get this message:The type or namespace name ‘LayoutAttributeAttribute’ does not exist in the namespace ‘Microsoft.AspNetCore.Components’What do I do?
Hi Eric,
Go to _Imports and remove @using Microsoft.AspNetCore.Components.Layouts , hope this will help.
Hello friends, after upgrade when publiish I get this error in blazor client:
rzc generate exited with code 2Point to: <RazorGenerate Debug=”$(_RazorDebugGenerateCodeTask)” DebugTool=”$(_RazorDebugGenerateCodeTool)” ToolAssembly=”$(_RazorToolAssembly)” UseServer=”$(UseRazorBuildServer)” ForceServer=”$(_RazorForceBuildServer)” PipeName=”$(_RazorBuildServerPipeName)” Version=”$(RazorLangVersion)” RootNamespace=”$(RootNamespace)” CSharpLanguageVersion=”$(LangVersion)” Configuration=”@(ResolvedRazorConfiguration)” Extensions=”@(ResolvedRazorExtension)” Sources=”@(RazorGenerateWithTargetPath)” ProjectRoot=”$(MSBuildProjectDirectory)” TagHelperManifest=”$(_RazorTagHelperOutputCache)” />
Ricardo, I had the same issue. Did you find a solution to the problem. I’m about to rollback my projetc to .NET 2.2. This latest release doesnt seem its ready.
Validation and Authorization look's Cool and Easy to Use, Way to Go.
JavaScript guys will keep demotivating blazor...Microsoft is heading towards right direction holding blazor..
This time nail this Javascript out of the way..Speed and light weight is the key to win the Market.
Keep complete control on Edge and Internet Explorer , Try to blindly adopt all features of crome to IE and edge.
Lastly ensure new features or best things is implemented to...
Nice with all the updates, however I think it will be good with somekind of youtube or channel9 video that demonstrates the newest version of blazor using an web app
Totally Agree, Video Tutor or GIF is always Good
Regarding the @ref issues - what ever happened to the code behind partial class feature that was supposedly being implemented? Did this feature get dropped?
If code-behinds were implemented from the start, you guys could have avoided a lot of hassle, and many of the clunky workarounds wouldn't be necessary. Mixing code and markup in the same file just feels wrong. I'm a huge Blazor fan, but this is the one thing that really bugs...
Thanks for contacting us, Daniel.
The support for
parital classes
will be added in 3.1 release. That work ist tracked at https://github.com/aspnet/AspNetCore/issues/5487Thanks Artak, that's fantactic news. It's a big relief to hear that partial classes is still planned for 3.1, as this is going to be a game changer, and I suspect a lot of people will prefer to have a clear separation of their markup and code.
If maintaining support for both mixed markup/code in the same file as well as partial clasess ends up causing complications, I'd be in favour of dropping the mixed...
Migrated existing project to Preview 8 and this is the issue l get:
Could not load type ‘Microsoft.AspNetCore.Components.UIMouseEventArgs’ from assembly ‘Microsoft.AspNetCore.Components, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
Ideas on how to resolve this will be welcomed.
Hi Teddy.
We’ve made some API changes during Preview8. The
UIMouseEventArgs
type is now part ofMicrosoft.AspNetCore.Components.Web
library.You can read more about this change in https://github.com/aspnet/AspNetCore/issues/12550.