10-21-2019, 06:51 PM
ASP.NET Core and Blazor updates in .NET Core 3.0 Preview 9
Daniel
September 4th, 2019
.NET Core 3.0 Preview 9 is now available and it contains a number of improvements and updates to ASP.NET Core and Blazor.
Here’s the list of what’s new in this preview:
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 9 install the .NET Core 3.0 Preview 9 SDK.
If you’re on Windows using Visual Studio, install the latest preview of Visual Studio 2019.
.NET Core 3.0 Preview 9 requires Visual Studio 2019 16.3 Preview 3 or later.
To install the latest Blazor WebAssembly template also run the following command:
Upgrade an existing project
To upgrade an existing ASP.NET Core app to .NET Core 3.0 Preview 9, 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 8 project to Preview 9:
You should now be all set to use .NET Core 3.0 Preview 9!
Blazor event handlers and data binding attributes moved to Microsoft.AspNetCore.Components.Web
In this release we moved the set of bindings and event handlers available for HTML elements into the Microsoft.AspNetCore.Components.Web.dll assembly and into the namespace. This change was made to isolate the web specific aspects of the Blazor programming from the core programming model. This section provides additional details on how to upgrade your existing projects to react to this change.
Blazor apps
Open the application’s root _Imports.razor and add. Blazor apps get a reference to the Microsoft.AspNetCore.Components.Web package implicitly without any additional package references, so adding a reference to this package isn’t necessary.
Blazor libraries
Add a package reference to the Microsoft.AspNetCore.Components.Web package package if you don’t already have one. Then open the root _Imports.razor file for the project (create the file if you don’t already have it) and add.
Troubleshooting guidance
With the correct references and using statement for, event handlers like and should be bold font and colorized as shown below when using Visual Studio.
If or are colorized as a normal HTML attribute, then the statement is missing.
If you’re missing a using statement for the namespace, you may see build failures. For example, the following build error for the code shown above indicates that the attribute wasn’t recognized:
In other cases you may get a runtime exception and the app fails to render. For example, the following runtime exception seen in the browser console indicates that the attribute wasn’t recognized:
Add a using statement for the namespace to address these issues. If adding the using statement fixed the problem, consider moving to the using statement app’s root _Imports.razor so it will apply to all files.
If you add the namespace but get the following build error, then you’re missing a package reference to the Microsoft.AspNetCore.Components.Web package:
Add a package reference to the Microsoft.AspNetCore.Components.Web package to address the issue.
Blazor routing improvements
In this release we’ve revised the Blazor component to make it more flexible and to enable new scenarios. The component in Blazor handles rendering the correct component that matches the current address. Routable components are marked with the directive, which adds the to the generated component classes. If the current address matches a route, then the renders the contents of its parameter. If no route matches, then the component renders the contents of its parameter.
To render the component with the matched route, use the new component passing in the supplied from the along with any desired parameters. The component will render the matched component with its layout if it has one. You can also optionally specify a default layout to use if the matched component doesn’t have one.
Render content using a specific layout
To render a component using a particular layout, use the new component. This is useful when specifying content for not found pages that you still want to use the app’s layout.
Routing decoupled from authorization
Authorization is no longer handled directly by the. Instead, you use the component. The component is a that will only render the matched component if the user is authorized. Authorization rules for specific components are specified using the . The component also sets up the as a cascading value if there isn’t one already. Otherwise, you can still manually setup the as a cascading value using the component.
You can optionally set the and parameters of the component to specify content to display if the user is not authorized or authorization is still in progress.
Route to components from multiple assemblies
You can now specify additional assemblies for the component to consider when searching for routable components. These assemblies will be considered in addition to the specified . You specify these assemblies using the parameter. For example, if is a routable component defined in a referenced class library, then you can support routing to this component like this:
Render multiple Blazor components from MVC views or pages
We’ve reenabled support for rendering multiple components from a view or page in a Blazor Server app. To render a component from a .cshtml file, use the HTML helper method with the desired .
RenderMode |
Description |
Supports parameters?
Static |
Statically render the component with the specified parameters. |
Yes
Server |
Render a marker where the component should be rendered interactively by the Blazor Server app. |
No
ServerPrerendered |
Statically prerender the component along with a marker to indicate the component should later be rendered interactively by the Blazor Server app. |
No
Support for stateful prerendering has been removed in this release due to security concerns. You can no longer prerender components and then connect back to the same component state when the app loads. We may reenable this feature in a future release post .NET Core 3.0.
Blazor Server apps also no longer require that the entry point components be registered in the app’s method. Only a single call to is required.
Smarter reconnection for Blazor Server apps
Blazor Server apps are stateful and require an active connection to the server in order to function. If the network connection is lost, the app will try to reconnect to the server. If the connection can be reestablished but the server state is lost, then reconnection will fail. Blazor Server apps will now detect this condition and recommend the user to refresh the browser instead of retrying to connect.
Utility base component classes for managing a dependency injection scope
In ASP.NET Core apps, scoped services are typically scoped to the current request. After the request completes, any scoped or transient services are disposed by the dependency injection (DI) system. In Blazor Server apps, the request scope lasts for the duration of the client connection, which can result in transient and scoped services living much longer than expected.
To scope services to the lifetime of a component you can use the new and base classes. These base classes expose a property of type that can be used to resolve services that are scoped to the lifetime of the component. To author a component that inherits from a base class in Razor use the directive.
Note: Services injected into the component using or the are not created in the component’s scope and will still be tied to the request scope.
Razor component unit test framework prototype
We’ve started experimenting with building a unit test framework for Razor components. You can read about the prototype in Steve Sanderson’s Unit testing Blazor components – a prototype blog post. While this work won’t ship with .NET Core 3.0, we’d still love to get your feedback early in the design process. Take a look at the code on GitHub and let us know what you think!
Helper methods for returning Problem Details from controllers
Problem Details is a standardized format for returning error information from an HTTP endpoint. We’ve added new and method overloads to controllers that use optional parameters to simplify returning Problem Detail responses.
New client API for gRPC
To improve compatibility with the existing implementation, we’ve changed our client API to use gRPC channels. The channel is where gRPC configuration is set and it is used to create strongly typed clients. The new API provides a more consistent client experience with , making it easier to switch between using the two libraries.
Support for async streams in streaming gRPC responses
gRPC streaming responses return a custom type that can be iterated on to receive all response messages in a streaming response. With the addition of async streams in C# 8, we’ve added a new extension method that makes for a more ergonomic API while consuming streaming responses.
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!
Daniel Roth
Principal Program Manager, ASP.NET
Follow Daniel https://devblogs.microsoft.com/aspnet/au...th27/feed/
Daniel
September 4th, 2019
.NET Core 3.0 Preview 9 is now available and it contains a number of improvements and updates to ASP.NET Core and Blazor.
Here’s the list of what’s new in this preview:
- Blazor event handlers and data binding attributes moved to Microsoft.AspNetCore.Components.Web
- Blazor routing improvements
- Render content using a specific layout
- Routing decoupled from authorization
- Route to components from multiple assemblies
- Render content using a specific layout
- Render multiple Blazor components from MVC views or pages
- Smarter reconnection for Blazor Server apps
- Utility base component classes for managing a dependency injection scope
- Razor component unit test framework prototype
- Helper methods for returning Problem Details from controllers
- New client API for gRPC
- Support for async streams in streaming gRPC responses
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 9 install the .NET Core 3.0 Preview 9 SDK.
If you’re on Windows using Visual Studio, install the latest preview of Visual Studio 2019.
.NET Core 3.0 Preview 9 requires Visual Studio 2019 16.3 Preview 3 or later.
To install the latest Blazor WebAssembly template also run the following command:
Code:
dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.0.0-preview9.19424.4To upgrade an existing ASP.NET Core app to .NET Core 3.0 Preview 9, 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 8 project to Preview 9:
- Update all Microsoft.AspNetCore.* package references to 3.0.0-preview9.19424.4
- In Blazor apps and libraries:
- Add a using statement for in your top level _Imports.razor file (see Blazor event handlers and data binding attributes moved to Microsoft.AspNetCore.Components.Web below for details)Code:
Microsoft.AspNetCore.Components.Web
- Add a using statement for in your top level _Imports.razor file.Code:
Microsoft.AspNetCore.Components.Authorization
- Update all Blazor component parameters to be public.
- Update implementations of to returnCode:
IJSRuntime.Code:ValueTask<T>
- Replace calls to with a single call toCode:
MapBlazorHub<TComponent>.Code:MapBlazorHub
- Update calls to andCode:
RenderComponentAsyncto use the new overloads toCode:RenderStaticComponentAsyncthat take aCode:RenderComponentAsyncparameter (see Render multiple Blazor components from MVC views or pages below for details).Code:RenderMode
- Update App.razor to use the updated component (see Blazor routing improvements below for details).Code:
Router
- (Optional) Remove page specific _Imports.razor file with the directive to use the default layout specified through the router instead.Code:
@layout
- Remove any use of the component and replace withCode:
PageDisplay,Code:LayoutView, orCode:RouteViewas appropriate (see Blazor routing improvements below for details).Code:AuthorizeRouteView
- Replace uses of withCode:
IUriHelper.Code:NavigationManager
- Remove any use of .Code:
@ref:suppressField
- Replace the previous code with the newCode:
RevalidatingAuthenticationStateProvidercode from the project template.Code:RevalidatingIdentityAuthenticationStateProvider
- Replace withCode:
Microsoft.AspNetCore.Components.UIEventArgsand remove the “UI” prefix from allCode:System.EventArgsderived types (Code:EventArgs->Code:UIChangeEventArgs, etc.).Code:ChangeEventArgs
- Replace withCode:
DotNetObjectRef.Code:DotNetObjectReference
- Replace andCode:
OnAfterRender()implementations withCode:OnAfterRenderAsync()orCode:OnAfterRender(bool firstRender).Code:OnAfterRenderAsync(bool firstRender)
- Add a using statement for
- In gRPC projects:
- Update calls to with a callCode:
GrpcClient.Createto create a new gRPC channel and new up your typed gRPC clients using this channel.Code:GrpcChannel.ForAddress
- Rebuild any project or project dependency that uses gRPC code generation for an ABI change in which all clients inherit from instead ofCode:
ClientBase. There are no code changes required for this change.Code:LiteClientBase
- Please also see the grpc-dotnet announcement for all changes.
- Update calls to
You should now be all set to use .NET Core 3.0 Preview 9!
Blazor event handlers and data binding attributes moved to Microsoft.AspNetCore.Components.Web
In this release we moved the set of bindings and event handlers available for HTML elements into the Microsoft.AspNetCore.Components.Web.dll assembly and into the
Code:
Microsoft.AspNetCore.Components.WebBlazor apps
Open the application’s root _Imports.razor and add
Code:
@using Microsoft.AspNetCore.Components.WebBlazor libraries
Add a package reference to the Microsoft.AspNetCore.Components.Web package package if you don’t already have one. Then open the root _Imports.razor file for the project (create the file if you don’t already have it) and add
Code:
@using Microsoft.AspNetCore.Components.WebTroubleshooting guidance
With the correct references and using statement for
Code:
Microsoft.AspNetCore.Components.WebCode:
@onclickCode:
@bindIf
Code:
@bindCode:
@onclickCode:
@usingIf you’re missing a using statement for the
Code:
Microsoft.AspNetCore.Components.WebCode:
@bindCode:
CS0169 The field 'Index.text' is never used
CS0428 Cannot convert method group 'Submit' to non-delegate type 'object'. Did you intend to invoke the method?In other cases you may get a runtime exception and the app fails to render. For example, the following runtime exception seen in the browser console indicates that the
Code:
@onclickCode:
Error: There was an error applying batch 2.
DOMException: Failed to execute 'setAttribute' on 'Element': '@onclick' is not a valid attribute name.Add a using statement for the
Code:
Microsoft.AspNetCore.Components.WebIf you add the
Code:
Microsoft.AspNetCore.Components.WebCode:
CS0234 The type or namespace name 'Web' does not exist in the namespace 'Microsoft.AspNetCore.Components' (are you missing an assembly reference?)Add a package reference to the Microsoft.AspNetCore.Components.Web package to address the issue.
Blazor routing improvements
In this release we’ve revised the Blazor
Code:
RouterCode:
RouterCode:
@pageCode:
RouteAttributeCode:
RouterCode:
FoundCode:
RouterCode:
NotFoundTo render the component with the matched route, use the new
Code:
RouteViewCode:
RouteDataCode:
RouterCode:
RouteViewCode:
<Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound>
</Router>To render a component using a particular layout, use the new
Code:
LayoutViewCode:
<Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" /> </Found> <NotFound> <LayoutView Layout="typeof(MainLayout)"> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </LayoutView> </NotFound>
</Router>Authorization is no longer handled directly by the
Code:
RouterCode:
AuthorizeRouteViewCode:
AuthorizeRouteViewCode:
RouteViewCode:
AuthorizeAttributeCode:
AuthorizeRouteViewCode:
AuthenticationStateCode:
AuthenticationStateCode:
CascadingAuthenticationStateCode:
<Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <CascadingAuthenticationState> <LayoutView Layout="@typeof(MainLayout)"> <p>Sorry, there's nothing at this address.</p> </LayoutView> </CascadingAuthenticationState> </NotFound>
</Router>You can optionally set the
Code:
NotAuthorizedCode:
AuthorizingCode:
AuthorizedRouteViewCode:
<Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"> <NotAuthorized> <p>Nope, nope!</p> </NotAuthorized> </AuthorizeRouteView> </Found>
</Router>You can now specify additional assemblies for the
Code:
RouterCode:
AppAssemblyCode:
AdditionalAssembliesCode:
Component1Code:
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Component1).Assembly }> ...
</Router>We’ve reenabled support for rendering multiple components from a view or page in a Blazor Server app. To render a component from a .cshtml file, use the
Code:
Html.RenderComponentAsync<TComponent>(RenderMode renderMode, object parameters)Code:
RenderModeRenderMode |
Description |
Supports parameters?
Static |
Statically render the component with the specified parameters. |
Yes
Server |
Render a marker where the component should be rendered interactively by the Blazor Server app. |
No
ServerPrerendered |
Statically prerender the component along with a marker to indicate the component should later be rendered interactively by the Blazor Server app. |
No
Support for stateful prerendering has been removed in this release due to security concerns. You can no longer prerender components and then connect back to the same component state when the app loads. We may reenable this feature in a future release post .NET Core 3.0.
Blazor Server apps also no longer require that the entry point components be registered in the app’s
Code:
ConfigureCode:
MapBlazorHub()Smarter reconnection for Blazor Server apps
Blazor Server apps are stateful and require an active connection to the server in order to function. If the network connection is lost, the app will try to reconnect to the server. If the connection can be reestablished but the server state is lost, then reconnection will fail. Blazor Server apps will now detect this condition and recommend the user to refresh the browser instead of retrying to connect.
Utility base component classes for managing a dependency injection scope
In ASP.NET Core apps, scoped services are typically scoped to the current request. After the request completes, any scoped or transient services are disposed by the dependency injection (DI) system. In Blazor Server apps, the request scope lasts for the duration of the client connection, which can result in transient and scoped services living much longer than expected.
To scope services to the lifetime of a component you can use the new
Code:
OwningComponentBaseCode:
OwningComponentBase<TService>Code:
ScopedServicesCode:
IServiceProviderCode:
@inheritsCode:
@page "/users"
@attribute [Authorize]
@inherits OwningComponentBase<Data.ApplicationDbContext> <h1>Users (@Service.Users.Count())</h1>
<ul> @foreach (var user in Service.Users) { <li>@user.UserName</li> }
</ul>Note: Services injected into the component using
Code:
@injectCode:
InjectAttributeRazor component unit test framework prototype
We’ve started experimenting with building a unit test framework for Razor components. You can read about the prototype in Steve Sanderson’s Unit testing Blazor components – a prototype blog post. While this work won’t ship with .NET Core 3.0, we’d still love to get your feedback early in the design process. Take a look at the code on GitHub and let us know what you think!
Helper methods for returning Problem Details from controllers
Problem Details is a standardized format for returning error information from an HTTP endpoint. We’ve added new
Code:
ProblemCode:
ValidationProblemCode:
[Route("/error")]
public ActionResult<ProblemDetails> HandleError()
{ return Problem(title: "An error occurred while processing your request", statusCode: 500);
}To improve compatibility with the existing
Code:
Grpc.CoreCode:
Grpc.CoreCode:
// Old
using var httpClient = new HttpClient() { BaseAddress = new Uri("https://localhost:5001") };
var client = GrpcClient.Create<GreeterClient>(httpClient); // New
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new GreeterClient(channel); var reply = await client.GreetAsync(new HelloRequest { Name = "Santa" });gRPC streaming responses return a custom
Code:
IAsyncStreamReaderCode:
// Old
while (await requestStream.MoveNext(CancellationToken.None))
{ var message = requestStream.Current; // …
} // New and improved
await foreach (var message in requestStream.ReadAllAsync())
{ // …
}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!
Daniel Roth
Principal Program Manager, ASP.NET
Follow Daniel https://devblogs.microsoft.com/aspnet/au...th27/feed/

