Introduction

Embracing a user-centric approach, Blazor has innovatively augmented its capabilities with its new server-side rendering mode, which empowers developers to effortlessly model bind and validate HTTP form post values. This advancement not only streamlines the developer's work with forms and data validation but also enhances page navigation and form handling, providing a seamlessly smooth user experience reminiscent of single-page applications (SPAs). The transformative features include simplified data binding with the [SupplyParameterFromForm] attribute, enhanced page navigation, and even compatibility with Blazor WebAssembly for interactive rendering, amidst other vital improvements. This discussion delves into the details and utility of these new capabilities, emphasizing how they elevate server-side rendering and data management in Blazor applications.

Assemblysoft provides custom development services targeting .NET MAUI

If you would like some assistance with .NET MAUI | Azure | Azure DevOps Services | Blazor Development then please get in touch, we would be glad to help.

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:

Blazor template option for server interactivity

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.

Conclusion

Blazor’s new enhancements in server-side rendering, form model binding, and validation mark a substantial leap towards creating more robust and user-friendly web applications. By simplifying data binding from form requests, facilitating enhanced page navigation, and ensuring smoother user experiences through advanced DOM preservation techniques, developers can now create applications that are not only powerful but also highly interactive and responsive. Moreover, the innovations in Blazor WebAssembly rendering open up new horizons for hybrid applications that effectively combine server-side and client-side rendering, underlining Blazor's commitment to versatility and developer empowerment. As we anticipate the removal of current limitations and further improvements in subsequent releases, these advancements undeniably strengthen the position of Blazor as a formidable tool in modern web development.

At Assemblysoft we specialise in Custom Software Development tailored to your requirements. We can onboard and add value to your business rapidly. We are an experienced Full-stack development team able to provide specific technical expertise or manage your project requirements end to end. We specialise in the Microsoft cloud and .NET Solutions and Services. Our developers are Microsoft Certified. We have real-world experience developing .NET applications and Azure Services for a large array of business domains. If you would like some assistance with Azure | Azure DevOps Services | Blazor Development | .NET MAUI Development or in need of custom software development, from an experienced development team in the United Kingdom, then please get in touch, we would love to add immediate value to your business.

Assemblysoft - Your Safe Pair of Hands

https://assemblysoft.com/