ASP.NET Core updates in .NET 8 Preview 6
.NET 8 Preview 6 is now available and includes many great new improvements to ASP.NET Core.
Here’s a summary of what’s new in this preview release:
- Improved startup debugging experience
- Blazor
- Form model binding & validation with server-side rendering
- Enhanced page navigation & form handling
- Preserve existing DOM elements with streaming rendering
- Specify component render mode at the call site
- Interactive rendering with Blazor WebAssembly
- Sections improvements
- Cascade query string values to Blazor components
- Blazor Web App template option for enabling server interactivity
- Blazor template consolidation
- Metrics
- Testing metrics in ASP.NET Core apps
- New, improved, and renamed counters
- API authoring
- Complex form binding support in minimal APIs
- Servers & middleware
- HTTP.sys kernel response buffering
- Redis-based output-cache
For more details on the ASP.NET Core work planned for .NET 8 see the full ASP.NET Core roadmap for .NET 8 on GitHub.
Get started
To get started with ASP.NET Core in .NET 8 Preview 6, install the .NET 8 SDK.
If you’re on Windows using Visual Studio, we recommend installing the latest Visual Studio 2022 preview. If you’re using Visual Studio Code, you can try out the new C# Dev Kit. If you are on macOS, you can now develop using Visual Studio for Mac 17.6.1 after enabling the preview feature for .NET 8 in Preferences.
Upgrade an existing project
To upgrade an existing ASP.NET Core app from .NET 8 Preview 5 to .NET 8 Preview 6:
- Update the target framework of your app to
net8.0
. - Update all Microsoft.AspNetCore.* package references to
8.0.0-preview.6.*
. - Update all Microsoft.Extensions.* package references to
8.0.0-preview.6.*
.
See also the full list of breaking changes in ASP.NET Core for .NET 8.
Improved startup debugging experience
Last preview we introduced debugging improvements to HttpContext
and friends. In .NET 8 Preview 6 we’ve improved the debugging experience for the WebApplication
type.
WebApplication
is the default way to configure and start ASP.NET Core apps in Program.cs
. Debug customization attributes have been applied to WebApplication
to highlight important information, such as configured endpoints, middleware, and IConfiguration
values in your IDE’s debugger.
.NET 7
.NET 8
See the ASP.NET Core ❤️ Debugging GitHub issue for more information about debugging improvements in .NET 8.
Blazor
Form model binding & validation with server-side rendering
Blazor’s new server-side rendering mode can now model bind and validate HTTP form post values.
To bind data from a form request, apply the [SupplyParameterFromForm]
attribute to a component property. Data in the request that matches the name of the property will be bound to the property. The property can be a primitive type, complex type, collection, or dictionary. Server-side validation using data annotations is also supported as well.
Movie.cs
public class Movie
{
public int Id { get; set; }
public string? Title { get; set; }
public DateOnly? ReleaseDate { get; set; }
public string? Genre { get; set; }
public decimal Price { get; set; }
}
Pages/Movies/Create.razor
@page "/movies/create"
@inject BlazorMovieContext DB
<PageTitle>Create</PageTitle>
<h1>Create</h1>
<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
<EditForm method="post" Model="Movie" OnValidSubmit="AddMovie">
<DataAnnotationsValidator />
<ValidationSummary class="text-danger" />
<div class="mb-3">
<label for="title" class="form-label">Title:</label>
<InputText id="title" @bind-Value="Movie.Title" class="form-control" />
<ValidationMessage For="() => Movie.Title" class="text-danger" />
</div>
<div class="mb-3">
<label for="release-date" class="form-label">Release date:</label>
<InputDate id="release-date" @bind-Value="Movie.ReleaseDate" class="form-control" />
<ValidationMessage For="() => Movie.ReleaseDate" class="text-danger" />
</div>
<div class="mb-3">
<label for="genre" class="form-label">Genre:</label>
<InputText id="genre" @bind-Value="Movie.Genre" class="form-control" />
<ValidationMessage For="() => Movie.Genre" class="text-danger" />
</div>
<div class="mb-3">
<label for="price" class="form-label">Price:</label>
<InputNumber id="price" @bind-Value="Movie.Price" min="0" step="0.01" class="form-control" />
<ValidationMessage For="() => Movie.Price" class="text-danger" />
</div>
<button type="submit" class="btn btn-primary">Create</button>
</EditForm>
</div>
</div>
<div>
@if (movieAdded)
{
<span>
Movie was added.
</span>
}
<a href="/movies">Back to List</a>
</div>
@code {
[SupplyParameterFromForm]
public Movie Movie { get; set; } = new();
private bool movieAdded = false;
public async Task AddMovie()
{
DB.Movie.Add(Movie);
await DB.SaveChangesAsync();
movieAdded = true;
}
}
If there are multiple forms on a page they can be distinguished using the Name
parameter, and you can use the Name
property on the [SupplyParameterFromForm]
to indicate which form you wish to bind data from.
You no longer need to set up a CascadingModelBinder
component to enable model binding. It’s now set up for you automatically.
Enhanced page navigation & form handling
Blazor will now enhance page navigation and form handling by intercepting the request in order to apply the response to the existing DOM preserving as much as possible. The enhancement avoids the need to fully load the page and provides a much smoother user experience, similar to a single page app (SPA), even though the app is still being server-side rendered.
In this preview release, enhanced navigation and form handling isn’t yet compatible with having interactive (Server or WebAssembly) components on the page at the same time. If your app uses interactive components, enhanced navigation will automatically be disabled. This limitation will be addressed in an upcoming preview before the .NET 8 GA release.
Preserve existing DOM elements with streaming rendering
Blazor streaming rendering will now preserve existing DOM elements when streaming updates into the page, which provides a faster and smoother user experience.
Specify component render mode at the call site
You can now specify the render mode for a component instance using the @rendermode
directive attribute. The render mode will then apply to the component and its children. For example,
<Counter @rendermode="@RenderMode.Server" />
To enable call site @rendermode
usage, make sure to set the Razor Language Version in the project file to 8.0
. This will be handled internally in the framework and won’t be necessary from the next preview release. To do this, edit your project’s .csproj
file, adding the following line into the first <PropertyGroup>
element:
<RazorLangVersion>8.0</RazorLangVersion>
Interactive rendering with Blazor WebAssembly
You can now enable interactive rendering of components with Blazor WebAssembly. While this option is not yet exposed on the Blazor Web App template, you can enable it manually.
To enable support for the WebAssembly render mode in your Blazor project, add the related services by calling app.Services.AddRazorComponents().AddWebAssemblyComponents()
and add the WebAssembly render mode by calling app.MapRazorComponents<App>().AddWebAssemblyRenderMode()
. Any components you wish to render on WebAssembly will need to be downloaded along with all of their dependencies to the browser. You’ll need to setup a separate Blazor WebAssembly project to handle building any WebAssembly specific code and reference it from your Blazor app.
You can specify the WebAssembly interactive render mode for a component by adding the [RenderModeWebAssembly]
attribute to the component definition or by specifying @rendermode="@RenderMode.WebAssembly"
on a component instance. Components that you setup to render on WebAssembly will also be prerendered from the server by default, so be sure either to author your components so they render correctly in either environment or disable prerendering when specifying the render mode: [RenderModeWebAssembly(prerender: false)]
or @rendermode="@(new WebAssemblyRenderMode(prerender: false))
.
Here’s a sample showcasing how to set up WebAssembly-based interactivity for a Counter
component that is rendered from the Index
page.
Note that there’s currently a limitation where components with routes must be defined in the same assembly as the App
component passed to MapRazorComponents<App>()
, so they cannot currently be defined in the client assembly. This will be addressed in a future update.
Blazor sections improvements
We’ve made the following improvements to how Blazor sections interact with other Blazor features:
- Cascading values: Cascading values will now flow into section content from where the content is defined instead of where it is rendered in a section outlet.
- Error boundaries: Unhandled exceptions will now be handled by error boundaries defined around the section content instead of around the section outlet.
- Streaming rendering: Whether section content will use streaming rendering is now determined by the component where the section content is defined instead of by the component that defines the section outlet.
Cascade query string values to Blazor components
You can now receive query string parameter values in any component, not just @page
components, using the [SupplyParameterFromQuery]
attribute. For example:
[SupplyParameterFromQuery]
public int PageIndex { get; set; }
It is no longer necessary to add the [Parameter]
attribute to any property that declares [SupplyParameterFromQuery]
.
Blazor Web App template option for enabling server interactivity
The Blazor Web App template now provides an option in Visual Studio for enabling interactivity using the server render mode:
The same option is already available from the command-line:
dotnet new blazor --use-server
Blazor template consolidation
As part of unifying the various Blazor hosting models into a single model in .NET 8, we’re also consolidating the number of Blazor project templates. In this preview release we’ve removed the Blazor Server template and the “ASP.NET Core hosted” option from the Blazor WebAssembly template. Both of these scenarios will be represented by options when using the new Blazor Web App template.
Metrics
Testing metrics in ASP.NET Core apps
In an earlier .NET 8 preview, we introduced ASP.NET Core metrics. It’s now easier to test metrics in ASP.NET Core apps.
ASP.NET Core uses the IMeterFactory
API to create and obtain meters. The meter factory integrates metrics with dependency injection, making isolating and collecting metrics easy. IMeterFactory
is especially useful for unit testing, where multiple tests can run side-by-side and you want to only gather data for your test.
The sample below shows how to use IMeterFactory
and MetricCollector<T>
(a simplified way to collect a counter’s data) in an ASP.NET Core functional test:
public class BasicTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
public BasicTests(WebApplicationFactory<Program> factory) => _factory = factory;
[Fact]
public async Task Get_RequestCounterIncreased()
{
// Arrange
var meterFactory = _factory.Services.GetRequiredService<IMeterFactory>();
var collector = new MetricCollector<double>(meterFactory, "Microsoft.AspNetCore.Hosting", "http-server-request-duration");
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync("/");
// Assert
Assert.Equal("Hello World!", await response.Content.ReadAsStringAsync());
await collector.WaitForMeasurementsAsync(minCount: 1);
Assert.Collection(collector.GetMeasurementSnapshot(),
measurement =>
{
Assert.Equal("http", measurement.Tags["scheme"]);
Assert.Equal("GET", measurement.Tags["method"]);
Assert.Equal("/", measurement.Tags["route"]);
});
}
}
New, improved, and renamed counters
ASP.NET continues to improve its support for metrics by adding new counters and improving existing counters. We want to make ASP.NET Core apps observable in reporting dashboards and to enable custom alerts.
New counters in this preview:
routing-match-success
androuting-match-failure
report how the request was routed in the app. If the request successfully matches a route, the counter includes information about the route pattern and whether it was a fallback route.diagnostics-handler-exception
is added to the exception handling middleware. The counter reports how unhandled exceptions are processed, and includes information about the exception name and handler result.http-server-unhandled-requests
is a new counter in ASP.NET Core hosting. It reports when an HTTP request reaches the end of the middleware pipeline without being handled by the app.- Various new rate limiting middleware counters make it possible to observe the number of requests holding leases, the number of requests queued, queue duration, and more.
Improved counters:
kestrel-connection-duration
now includes the connection HTTP protocol and TLS protocol.signalr-http-transport-current-connections
now includes the connection transport type.
Finally, based on testing ASP.NET Core with cloud-native tools, we’ve renamed all ASP.NET Core counters to include more information in the name. Counters were renamed to make them identifiable by name alone and to reduce the chance of naming conflicts. For example, request-duration
was renamed to http-server-request-duration
.
API authoring
Complex form binding support in minimal APIs
In .NET 8 Preview 4 we expanded support for form binding in minimal APIs to handle certain form-based parameters without the need of the FromForm
attribute. This was limited to parameter types including
IFormCollection
, IFormFile
, and IFormFileCollection
. Minimal APIs now supports form-binding for more complex scenarios, including:
- Collections, like
List
andDictionary
- Complex types, like
Todo
orProject
The sample below showcases a minimal endpoint that binds a multi-part form input to a complex object. It also outlines how to use the anti-forgery services in ASP.NET to support the generation and validation of anti-forgery tokens in minimal APIs. Key points to note in this sample include:
- The target parameter must be annotated with the
[FromForm]
attribute to disambiguate from parameters that should be read from the JSON body. - Binding to
record
types is not currently supported, so complex types must be implemented as a class. - Recursive binding is not supported, so the
Todo
type does not contain any recursive references.
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAntiforgery();
var app = builder.Build();
app.MapGet("/", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
var html = $"""
<html>
<body>
<form action="/todo" method="POST" enctype="multipart/form-data">
<input name="{token.FormFieldName}" type="hidden" value="{token.RequestToken}" />
<input type="text" name="name" />
<input type="date" name="dueDate" />
<input type="checkbox" name="isCompleted" />
<input type="submit" />
</form>
</body>
</html>
""";
return Results.Content(html, "text/html");
});
app.MapPost("/todo", async Task<Results<Ok<Todo>, BadRequest<string>>> ([FromForm] Todo todo, HttpContext context, IAntiforgery antiforgery) =>
{
try
{
await antiforgery.ValidateRequestAsync(context);
return Results.Ok(todo);
}
catch (AntiforgeryValidationException e)
{
return TypedResults.BadRequest("Invalid anti-forgery token");
}
});
app.Run();
class Todo
{
public string Name { get; set; } = string.Empty;
public bool IsCompleted { get; set; } = false;
public DateTime DueDate { get; set; } = DateTime.Now.Add(TimeSpan.FromDays(1));
}
Servers & middleware
HTTP.sys kernel response buffering
You can now enable kernel-based response buffering when using HTTP.sys using the EnableKernelResponseBuffering
option. This option can improve response times, particularly when writing large responses with lots of small writes to a client with high latency. In affected scenarios, this can drastically improve response times from minutes (or outright failure) to seconds.
Redis-based output caching
Output caching was introduced in .NET 7 and allows entire responses to be cached and replayed, reducing server processing. By default, cached responses are stored in-process, so each server node has a separate and isolated cache that is lost whenever the server process is restarted. As an alternative, we’re now introducing the ability to use a Redis backend for output caching, providing consistency between server nodes via a shared cache that outlives individual server processes.
To setup Redis-based output caching, add a package reference to Microsoft.Extensions.Caching.StackExchangeRedis
and then configure the required services by calling app.Services.AddStackExchangeRedisOutputCache(...)
. The available configuration options are identical to the existing Redis-based distributed caching options. You can provide your own Redis server, or use a hosted offering such as Azure Cache for Redis.
Give feedback
We hope you enjoy this preview release of ASP.NET Core in .NET 8. Let us know what you think about these new improvements by filing issues on GitHub.
Thanks for trying out ASP.NET Core!
66 comments
As exciting new Blazor United feature come together, are there any videos to help newcomers ‘visualise’ how all the pieces you mention work togerher? Many thanks.
Hi Rod. You can check out the Blazor session recordings from Microsoft Build:
These recordings we’re still based on the original Blazor “United” prototype bits that Steve Sanderson initially put together to kick off our .NET 8 Blazor efforts, but we’re getting pretty close to being enabling all the shown functionality in .NET 8. We need to finish up the WebAssembly render mode and add the auto render mode.
Yes it would be nice to clarify somehow the context, there are so many ‘interactice’ render modes mentioned here, some has template some does not. I feel confused about them (even after seeing the Build sessions).
“add the auto render mode.”
Ah, it would have been nice to know thats not implemented yet – have spent several days off and on trying to get “RenderModeAuto” working after watching the linked videos 😁
Still, most impressed by whats here already, and whats coming. Convinced me to do our next big cloud project in Blazor Server.
Could not agree more. I’m trying to learn Blazor, but confused very much because of these changes.
I did a more expansive explanations of the new Blazor capabilities in .NET 8 in a .NET Community Standup a few months back that might help. It goes into more detail than we had time to do at Build.
I’ll try to summarize some of the key points here:
We understand that this is a lot of new stuff to digest. We will of course have docs, videos, samples, tutorials that will help folks get oriented by the time we ship a stable release of .NET 8 later this year.
But for now, I hope this helps. Feel free to ask questions if anything is unclear.
Hi,
You will need separate training for the new blazor devs who don’t care about how it was before.
And separate training for the existing blazor devs who need to forget how it was before.
Thanks for your great work!
so something like react server components
Correct, the models are very similar, except with Blazor you get to write C# instead of JavaScript and you get the full performance and scalability benefits of the .NET runtime on the server.
So basically Blazor now will be closer to Hotwired (Turbo)? If i get it right, instead of keeping a live WebSocket (which might be expensive in some cases), now the idea will be to have a component send classic HTTP reqs? and in the need of interactivity the Blazor WASM will be the main tool ? If i understand this right, it seems Blazor comes closer to the Hotwired stack that uses Turbo and Stimulus for the HTTP requests and then for the interactivity.
So to sum it up, is Blazor becoming stateless? Also, the way to keep a stateful connection via a WebSocket will remain? Although it is expensive, i believe there are some nice scenarios that the WebSocket and a stateful component could be a good idea.
Thanks in advance
Hi George. Blazor will support both stateless and stateful scenarios using the same component model. You’ll still be able to make the entire app interactive and stateful like you can today with Blazor Server or Blazor WebAssembly. We’re adding support for traditional server-side rendering (SSR) with Blazor components as well as some SSR based progressive enhancements, like enhanced navigation & form handling and streaming rendering. But you can also switch specific components to use a stateful interactive render mode based on either Blazor Server or Blazor WebAssembly. This means you can have islands of interactivity in what is otherwise a stateless web app.
However, now is not the right time to learn this framework, because until it reaches the final stage, changes are constantly applied to it, which is confusing for me.
The todo arg of the MapPost lambda is missing its type definition 😉
Ah, good catch! Should be fixed now.
I think there are two things missing in this blog post:
For @rendermode=”@RenderMode.Server” you need to call AddServerRenderMode():
app.MapRazorComponents().AddServerRenderMode();
For AddWebAssemblyComponents() you need:
Hi,
Is it possible to set render mode one time globally? I prefer to have
Auto
always. Renders on server mode first, then after fetching all required files, it will switch to client mode.Do we have an option for it now?
Thanks for your great job.
Hi Hamed. The render mode gets inherited down the component hierarchy, so you can set your desired render mode at the root and it will then apply to all child components. For example, here is a sample that sets up a Blazor app to use Blazor Server, similar to the existing Blazor Server template: https://github.com/danroth27/Net8BlazorServer. We haven’t finished implementing the auto render mode yet (it’s coming soon!) but when we do you will be able to similarly apply it to the root of your app.
Hi Dan,
I’m starting a new project in about two weeks and would like to already bet on .NET 8 Fullstack Blazor instead of locking in on .NET 7 Blazor WASM + ASP.NET Core WebApi. However, for this the auto mode has been deemed a necessary requirement. Can I interpret your “it’s coming soon” as “will be ready with preview7 mid August”?
In any case: do you feel the systems are stable enough to start with @rendermode=”@RenderMode.WebAssembly” on the root component in two weeks and then simply switch that to auto once available and it will justworkTM or would we have to do some serious refactoring?
Would appreciate your feedback so that I can give a qualified recommendation to my manager.
(I have to agree with some other comments: even reading all posts coming out I’m now pretty confused which render mode does what and how the project setup would look like in each case.)
Thanks!
Yup, that’s the plan, but plans can and do change. The work is tracked by https://github.com/dotnet/aspnetcore/issues/46397.
I think you may hit some significant limitations right now with the WebAssembly render mode that may prove problematic. For example, component discovery still needs some work. I think you’ll have a better time using the Server render mode right now.
As with any preview release, we can’t guarantee that there still won’t be some disruptive changes. If you want to make sure you’re building against something that closely resembles what the final stable release will look like, you might want to wait for the first .NET 8 release candidate in September, which should be feature complete.
Thanks for the response! We are aware that preview means preview, but you’ve been quite reliable in the past, so I think it is fine to lay the groundwork with the last preview. RC (and the go-live) will be here in time before any deployment happens.
Alright, then we will start with server render mode, during the first dev phase latency won’t be an issue anyway 👍
In a similar position to Markus – starting a new long term project and would definitely prefer to implement it in .Net Blazor.
Would starting with Blazor 7 Server be easy to upgrade to 8 or would you recommend starting with Blazor 8 Preview 6?
Hi Lindsay. If you need to go into production any time soon, then .NET 7 is the recommended release to use, as .NET 8 is still in preview. You’ll be able to easily update your .NET 7 Blazor app to .NET 8, and we will provide guidance on how to move to the full stack web UI model in .NET 8 if that’s what you want to do.
Incredible list of updates for Blazor! Will it be possible to have multiple Blazor WebAssembly apps, so I can map a specific WASM setup to a specific area in the website somehow?
Hi Rogier. No, unfortunately the work needed to be able to run multiple Blazor apps on the same page isn’t going to make it for .NET 8. Note that running multiple Blazor WebAssembly apps on the same page would likely have significant overhead due to the cost of potentially downloading multiple copies of the .NET WebAssembly runtime and core framework libraries. You will, however, in .NET 8 be able to render multiple separate components or pages within a Blazor app using WebAssembly.
I follow the Blazor development (read the blogs watch videos from build) and I have trouble keeping up with the terminology. For example I have no idea what “interactive rendering” is. The docs should start with a page about what different terms that end in “rendering” mean.
Hi Stilgar. This is good feedback. We will be updating the Blazor docs to explain the various Blazor render modes and patterns for .NET 8. To answer your specific question, interactive rendering refers to being able to handle UI events, like a click or change event. Blazor supports this level of UI interactivity by either handling the event over a real-time connection to the server or by handling the event directly in the browser via WebAssembly. This is in contrast to traditional server-side rendering (SSR), where the user interaction is over once the request to the server is completed.
So we have Server rendering (which presumably means Blazor Server and real-time connection), Client rendering (which means Blazor Wasm), server prerendering which means executing on the server and sending the HTML on first load, streaming rendering which means that prerendering uses HTTP streaming and can send the page in chunks and we have interactive rendering which means Server or Client rendering. Do we have a word for server prerendered stuff that can also accept normal form submits or this is paired with server prerendering?
This is traditional, stateless, server-side rendering (SSR), the same pattern that is used by MVC, Razor Pages, and other long-standing web frameworks like ASP.NET Web Forms, Django, PHP, etc. Traditional SSR is different from the Blazor Server based render mode, which also renders from the server but enables a stateful programming model and rich interactivity. This distinction is admittedly confusing and has been the source of much internal discussion. We certainly welcome discussion on improved terminology. If you have thoughts on this, please let us know by opening an issue in our GitHub repo.
I know that it is different from Blazor server, but in .NET 7 the prerendering feature responds with HTML from the server but can’t accept form submits. Will the new feature be added and handled with what is now called RenderMode.WebAssemblyPrerendered or RenderMode.ServerPrerendered or there is another word for when submits are possible?
The new server-side rendering support in Blazor in .NET 8 includes the ability to handle tradition form submission requests. Form submission requests will get routed to the right component on the server just like any SSR based request. You can use the new [SupplyParameterFromForm] attribute to bind request data in your components. EditForm will fire the normal submit events when a submission is received.
Could you help me clarify questions about “interactive rendering”.
The posts says:
You can now enable interactive rendering of components with Blazor WebAssembly. While this option is not yet exposed on the Blazor Web App template, you can enable it manually.
But later the posts also says:
The Blazor Web App template now provides an option in Visual Studio for enabling interactivity using the server render mode:
Are these the same thing?
If I would like to move an existing application (webassembly with pre-render and even state is sent to the UI) to interactive rendering, which template shall I choose?
How shall I think about “blazor server”, “blazor client (or webassembly)” and “blazor server-side rendering” in the future? Which is the one I get as a default from the template?
I also see the sample separates the client and the server into separate projects, but I recall during the Build demo it was mentioned that now these become a single project. What is the recommendation, a single project? Are there any limitation on this side with Preview 6?
Yeah, the sample splits it for a simple reason: it does not work when everything is in one assembly. At least I couldn’t get it to work, some files WASM requires seem to not be generated during build.
As I wrote in my other comment I don’t see the reason for that either.
> The Blazor Web App template now provides an option in Visual Studio for enabling interactivity using the server render mode: Are these the same thing?
Hi Laszlo. By interactivity I mean the ability to handle UI events, like click and change events. Blazor supports this level of UI interactivity in two different ways: Blazor Server & Blazor WebAssembly. In .NET 8 you can choose on a per component or page basis if the component should be interactive and how that should be achieved. Currently you have to enable support for the interactive render modes. We now have a template option for enabling support for the Blazor Server based render mode, which will setup the necessary services and endpoints. We don’t have the same template option for the WebAssembly render mode yet, but you can enable it manually as shown in the sample app.
> If I would like to move an existing application (webassembly with pre-render and even state is sent to the UI) to interactive rendering, which template shall I choose?
You’re existing Blazor WebAssembly app is already interactive: you can already handle UI events, setup two-way data binding, etc. You should be able to simply update that app to target .NET 8 and it will continue to function without any other changes. But you may want to upgrade your app to use the new unified Blazor model so that you can take advantage of all of the new features, like server-side rendering, streaming rendering, enhanced navigation & form handling, and the ability to mix Blazor Server & Blazor WebAssembly in the same app. You’ll be able to do that too, and we will provide guidance on how to do this upgrade.
> How shall I think about “blazor server”, “blazor client (or webassembly)” and “blazor server-side rendering” in the future? Which is the one I get as a default from the template?
Prior to .NET 8, you had to choose between Blazor Server and Blazor WebAssembly up front as two different hosting models for your components. In .NET 8 you instead simply create a Blazor Web App and then you can choose on a per component or page bases how you want your components to render. What the defaults will be is an active area of discussion. Currently you don’t get any interactive render modes by default, but I think we’d like to get to a place where all of the interactive render modes are enabled by default. It’s not clear yet if we will get all the way there in .NET 8.
> I also see the sample separates the client and the server into separate projects, but I recall during the Build demo it was mentioned that now these become a single project. What is the recommendation, a single project? Are there any limitation on this side with Preview 6?
We’d really like to get to a single project model for Blazor, but getting the developer experience right is a tricky problem. You need separate build outputs for the server and the client and they have very different requirements: on the server you want full access to server capabilities, but on the client you need minimal dependencies and the download size to be small. We got strong feedback from the community that they prefer to manage the client build using a separate project, so for .NET 8 we’ve recently decided to stick with the existing multiple project setup, and we’ll revisit single project support later.
Thank you for the detailed answers 🙂
“You’ll need to setup a separate Blazor WebAssembly project to handle building any WebAssembly specific code and reference it from your Blazor app.”
Why is that a requirement? I’d prefer it if all components are in one assembly.
With the extra assembly for WASM capable components all of them will end up in the client assembly and the server assembly is just a thin frame.
Or would you recommend implementing the API in the server project as well? In my mind I still had a dedicated client project and another one for backend (so 1) backend, 2) client-server, 3) client-client as it stands).
Hi Markus. The client WebAssembly project is for managing what code and dependencies will be sent to the browser. It will be typically referenced by the server project. You can (and should!) share your components with the server and client. In general, we recommend that Blazor components be implemented so that they are agnostic to where they are running (server or client) so that you get maximum reuse. You just need to make sure your components are part of the dependency graphs of both the client and server. You can achieve that by putting components that need to be available on both client and server in the client project, or have a separate component library that is referenced by both the client and server projects.
Oh ok, I can see how it’s easier to determine what needs to be sent to the client with a separate project instead of removing hosting components from the server one – makes sense now.
I was planning on implementing (almost) all components as if they are only meant to run on the client, so that will work then. Might be a case for a folder in a solution right there to group the two client projects.
So cool, I’m always excited when I see a blazor preview blog post!
I wonder, will auth work well and seemlessly when we finally have the auto render mode?
Yes, we expect to support authentication with the auto render mode.
That’s so cool! The last puzzle piece! Thank you for all the hard work!
Hello Dan, from what I’ve seen auto mode has already been merged to release/preview7, but the auth template issue got pushed back to rc1 – is that a delay just for the template part or won’t the code parts for auth be ready either?
I saw some work for identity model upgrades, but unsre what the big picture ist there.
Would appreciate an update if you see auto mode + auth still on track for preview7, thanks.
Hi Markus. We’re working to land the Blazor authentication story, including when using auto, for RC1. We don’t expect it to be part of the upcoming Preview 7 release, which is pretty much locked down at this point.
Thanks for responding Dan! Not what I wanted to hear, but confirming what I suspected based on the recent activity.
We will start our project next week with an ‘old’ WASM-style frontend. You wrote above that there will be an upgrade path from pure-WASM to the new model (hope that still holds true) so I’ll look at that after RTM in November – if it’s manageable effort we’ll consider upgrading. And at least we’ll have the jiterpreter.
I really wanted to get started with the new bits right away and would have accepted some issues, but the basic foundations have to be there otherwise it doesn’t make much sense. When RC1 drops we’ll be almost two months in and that’s too long to just tinker with the backend without touching the frontend at all given the requirements.
Thanks to the team for the good work anyway! It’s quite a big task to get done and iron out all the quirks for just one year.
Thank you for all the great work!
The prerendering is cool!
But how do I run logic for an embedded server component on a SSR page component after it has been materialized in the browser? Like executing some JavaScript.
The OnAfterRender only run once for the server component. And that makes sense. But there perhaps should be another lifecycle event for this.
Hi Marina. We have some guidance related to this here: Prerendering with JavaScript interop. We are also considering how we can surface at runtime where the component is currently executing: https://github.com/dotnet/aspnetcore/issues/49401. Give the GitHub issue a 👍 if it’s important to you.