20 avril 2026

Migration Blazor Server de .NET 9 à .NET 10 : retour d’expérience

Pourquoi attendre .NET 10 pour migrer ?

J’attendais cette version avec impatience, notamment pour la résolution d’un bug de reconnexion Blazor Server que j’avais remonté moi-même : aspnetcore#64228. Ce problème affectait la fiabilité de la reconnexion automatique après une coupure réseau, et il était bloquant pour une application de type B2B utilisée en continu. Le fix est enfin intégré dans .NET 10, ce qui rendait la migration encore plus motivante.

1. Mise à jour du .csproj

Première étape, incontournable : changer la version cible dans le fichier projet.

<TargetFramework>net10.0</TargetFramework>
XML

C’est le point de départ obligatoire avant toute autre modification.

2. Mise à jour des packages NuGet

Une fois le framework mis à jour, il faut aligner tous les packages. Je mets à jour les dépendances Microsoft (Microsoft.AspNetCore.*, etc.) en version 10.x, ainsi que les packages tiers compatibles .NET 10. C’est le bon moment pour vérifier les éventuelles incompatibilités et nettoyer les dépendances obsolètes.

3. Les nouveaux fichiers de structure Blazor

C’est là que .NET 10 apporte les vraies nouveautés structurelles. J’ai créé un projet Blazor Server template vierge pour en extraire les fichiers modifiés.

NotFound.razor

Une page 404 dédiée fait maintenant partie du template par défaut. Elle s’enregistre directement dans Routes.razor via le nouvel attribut NotFoundPage :

<Router AppAssembly="typeof(App).Assembly"
        NotFoundPage="typeof(Pages.NotFound)" />
Razor

Plus besoin du bloc <NotFound> inline dans le routeur, c’est plus propre et mieux séparé.

ReconnectModal : la reconnexion repensée

La gestion de la reconnexion change aussi : elle est maintenant encapsulée dans trois fichiers dédiés :

  • ReconnectModal.razor pour le composant UI
  • ReconnectModal.razor.cs pour le code-behind
  • ReconnectModal.razor.js pour la logique de reconnexion côté client

Ce composant se place dans le <body> de App.razor :

<body>
    ...
    <ReconnectModal />
    <Routes />
</body>
Razor

Bonus i18n : j’en ai profité pour personnaliser ReconnectModal.razor.js afin de gérer la traduction automatique des messages de reconnexion. Le code est disponible sur mon GitHub : tossnet/Blazor-Reconnect-demo-i18n

4. Le script Blazor devient une ressource statique

Changement notable dans App.razor : le script Blazor passe par le système d’assets statiques. On utilise désormais @Assets[] :

<script src="@Assets["_framework/blazor.web.js"]"></script>
Razor

Cela permet au framework de gérer le cache-busting automatiquement via un fingerprint sur le nom du fichier.

5. ResourcePreloader dans le <head>

Dernier ajout à ne pas oublier : le composant <ResourcePreloader /> à placer dans le <head> :

<head>
    ...
    <ResourcePreloader />
</head>
HTML

Il injecte les balises <link rel="preload"> appropriées pour les ressources statiques, ce qui améliore les performances au chargement initial.

Récap des modifications

  1. Mettre à jour <TargetFramework>net10.0</TargetFramework> dans le .csproj
  2. Mettre à jour les packages NuGet vers les versions compatibles .NET 10
  3. Récupérer NotFound.razor, ReconnectModal.razor, .razor.cs et .razor.js depuis un projet template
  4. Ajouter NotFoundPage="typeof(Pages.NotFound)" sur <Router /> dans Routes.razor
  5. Remplacer le script Blazor par <script src="@Assets["_framework/blazor.web.js"]"></script>
  6. Ajouter <ReconnectModal /> dans le <body> et <ResourcePreloader /> dans le <head>

Pour aller plus loin

On a fait une émission DevApps dédiée aux nouveautés de Blazor en .NET 10 :

La migration est dans l’ensemble assez fluide. Le plus gros changement reste la restructuration de la reconnexion et des assets statiques, une bonne occasion de personnaliser le comportement selon vos besoins.

Laisser un commentaire