Skip to content

Experiment rendering interactive Razor components via Minimal API endpoints

Notifications You must be signed in to change notification settings

marinasundstrom/BlazorMinimalApiTest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Minimal API with interactive Razor component

Serving interactive Razor component through Minimal API endpoint - in .NET 8. Both Server and WebAssembly.

BlazorWasm

Description

Based on the dotnet new webapi template.

Adds extension method that exposes the blazor.web.js script as a static file.

To enable client WebAssembly support, there is another extension method that serves those files, including dotnet.js.

Guides for Server and WebAssembly below.

Endpoints: http://localhost:5277/server and http://localhost:5277/wasm?incrementBy=2

FAQ and Links to resources at the bottom.

Interactive Server components with Minimal API

Created components:

  • Counter - Interactive on the server.
  • MyPage - equivalent to an index.html page (Server-side rendered)

Register Razor component services:

builder.Services.AddRazorComponents()
    .AddServerComponents();

Serve the Blazor JS script:

app.UseBlazorWebJS()

Map endpoint:

app.MapGet("/test", () => new RazorComponentResult<BlazorMinimalApi.Components.MyPage>());

Map Blazor Hub - important for interactive Server components:

app.MapBlazorHub();

UseBlazorWebJS

Adds the route serving the blazor.web.js, which is essential to all interactivity.

Based on this file.

Adding WebAssembly support

You need to restructure your solution into having one Server project, and one Client project (for WebAssembly).

First. Create a standalone Blazor WebAssembly project for your client-side code.

dotnet new blazorwasm

Reference the client WebAssembly project from the Server project.

Server project

Add package reference:

dotnet add package Microsoft.AspNetCore.Components.WebAssembly.Server --prerelease

or add this to the .csproj:

<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0-rc.1.*" />

Update the Program.cs by adding a call to AddWebAssemblyComponents:

builder.Services.AddRazorComponents()
    .AddServerComponents()
    .AddWebAssemblyComponents();

Use custom extension method that maps endpoint that exposes Blazor framework files.

app.UseBlazorWebAssemblyRenderMode();

Then set the render mode of, for instance, Counter.

@attribute [RenderModeWebAssembly]

Or through the directive:

<Counter @rendermode="@RenderMode.WebAssembly" />

It is important that the WebAssembly component lives in the client project, otherwise it will not run in the browser.

Add routable pages

Recommended for ordinary apps

You can enable the standard page component routing, which works for both SSR and interactive pages. This is provided that you have declared the router in the root App component.

app.MapRazorComponents<App>()
    .AddWebAssemblyRenderMode()
    .AddServerRenderMode()
    .AddAdditionalAssemblies(typeof(Counter).Assembly);

The router in App.razor:

<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">

        </RouteView>
    </Found>
</Router>

And add the @page directive to your page components:

@page "/my-route"

Frequently asked questions

Is this supported?

No. It is not supported. Though the possibility to support it is there.

What is currently lacking in .NET 8 RC1, it that there is no way to map the required JavaScript files outside the specific APIs what the Blazor team had constructed.

Other than adding extension methods that map those static files, there is no magic here.

Why not invoke MapRazorComponents<T>?

Since it maps components to routes automatically - and you probably want control over the endpoints.

Why can't I serve an interactive component directly from ane endpoint?

Why must I put the interactive component in a component that is served as static SSR?

Because you need a static page within which you can host the interactive component - similar to an index.html. A structure of content which isn't affected by the interactivity,

This also re-assures that the script gets loaded first, and not reloaded with any interactive component.

What about layouts?

Page layouts are applied in combination with Blazor Router and RouteView. We aren't using, and we can't use this here.

This is thus no direct replacement for MVC and Razor Views.

If layouts are important to you, then I recommend you to consider routable page components. (See Add routable pages above)

Does JS Interop work?

Yes. It should just work since it is being registered with the Blazor services.

builder.Services.AddRazorComponents();

Notes

I'm not sure whether this will work with RenderModeAuto.

Links

About

Experiment rendering interactive Razor components via Minimal API endpoints

Topics

Resources

Stars

Watchers

Forks