Section courante

A propos

Section administrative du site

Migration d'ASP.NET vers ASP.NET Core

Évaluer ton application actuelle

Avant de migrer une application ASP.NET vers ASP.NET Core, il est crucial d'évaluer en profondeur l'architecture et les technologies utilisées actuellement. Cette étape permet de déterminer la faisabilité de la migration ainsi que les adaptations nécessaires. Il faut notamment identifier si l'application repose sur des composants non pris en charge par ASP.NET Core, comme Web Forms ou certains modules IIS. Les applications basées sur ASP.NET MVC ou Web API sont en général plus simples à migrer. Il est aussi important de recenser les bibliothèques tierces utilisées : certaines n'ont pas de versions compatibles .NET Core. Cette analyse vous permet de prioriser les tâches à réaliser et de choisir une stratégie de migration progressive ou totale. Sans cette évaluation, on risque de sous-estimer le temps, l'effort ou même la complexité du projet.

L'un des éléments fondamentaux à vérifier est l'utilisation de l'espace de noms System.Web, étant omniprésent dans les projets ASP.NET classiques. Cet espace de noms n'existe plus dans ASP.NET Core, ce qui implique de revoir entièrement la gestion des requêtes HTTP, des sessions, de l'authentification, etc. De plus, si ton application utilise fortement le fichier Web.config pour la configuration, il faudra adapter ces réglages dans les nouveaux fichiers appsettings.json et utiliser le système de configuration intégré. Il est aussi utile de lister les points d'entrée de l'application : Global.asax, Gestionnaires (ASHX), Modules,..., pour préparer leur remplacement. Cette étape peut paraître fastidieuse, mais elle évite bien des surprises en cours de migration. C'est aussi le bon moment pour analyser le code mort ou les fonctionnalités obsolètes qui ne valent peut-être pas la peine d'être migrées.

Enfin, évaluer les dépendances entre les différentes couches de l'application est essentiel pour planifier une migration modulaire. Si la logique métier, l'accès aux données ou les services tiers sont fortement couplés à ASP.NET, il faudra envisager un découplage préalable. Migrer ces composantes vers des bibliothèques compatibles .NET Standard ou .NET 6+ facilitera leur réutilisation dans un environnement ASP.NET Core. Il est aussi conseillé de faire un audit de sécurité et de performance : certains comportements implicites dans ASP.NET (comme la gestion des cookies ou la compression) doivent être explicitement configurés dans Core. Bref, plus l'évaluation initiale est précise, plus la suite du projet sera fluide et structurée. Une bonne préparation vaut toujours mieux qu'une migration précipitée.

Avant de commencer, posez-vous ces questions :

Fonction ASP.NET Web Forms Razor (ASP.NET Core) Vue.js Angular React
Étiquette (affichage) <asp:Label ID="lbl" runat="server" Text="..." /> <label>@Model.Texte</label> <label>{{ texte }}</label> <label{{ texte }}</label> <label>{texte}</label>
TextBox <asp:TextBox ID="txt" runat="server" /> <input asp-for="Nom" /> <input v-model="nom" /> <input [(ngModel)]="nom" /> <input value={nom} onChange={e => setNom(e.target.value)} />
Button <asp:Button ID="btn" runat="server" Text="OK" OnClick="btn_Click" /> <button type="submit">OK</button> <button @click="submit">OK</button> <button (click)="submit()">OK</button> <button onClick={submit}>OK</button>
CheckBox <asp:CheckBox ID="chk" runat="server" /> <input type="checkbox" asp-for="EstValide" /> <input type="checkbox" v-model="estValide" /> <input type="checkbox" [(ngModel)]="estValide" /> <input type="checkbox" checked={estValide} onChange={e => setEstValide(e.target.checked)} />
DropDownList <asp:DropDownList ID="ddl" runat="server" /> <select asp-for="Choix" asp-items="Model.ListeChoix"></select> <select v-model="choix"><option v-for="item in liste" :value="item.valeur">{{ item.texte }}</option></select> <select [(ngModel)]="choix"><option *ngFor="let item of liste" [value]="item.valeur">{{ item.texte }}</option></select> <select value={choix} onChange={e => setChoix(e.target.value)}>{liste.map(item => <option key={item.valeur} value={item.valeur}>{item.texte}</option>)}</select>
GridView <asp:GridView ID="gv" runat="server" /> @foreach (var item in Model.Liste) avec <table> <tr v-for="item in liste"><td>{{ item.nom }}</td></tr> <tr *ngFor="let item of liste"><td>{{ item.nom }}</td></tr> {liste.map(item => <tr key={item.id}><td>{item.nom}</td></tr>)}
Repeater <asp:Repeater ID="rep" runat="server" /> @foreach (var item in Model.Liste) { ... } <div v-for="item in liste">{{ item.nom }}</div> <div *ngFor="let item of liste">{{ item.nom }}</div> {liste.map(item => <div key={item.id}>{item.nom}</div>)}
Validation Message <asp:RequiredFieldValidator /> @Html.ValidationMessageFor(...) <span v-if="!nom">Nom requis</span> <div *ngIf="!nom">Nom requis</div> {!nom && <span>Nom requis</span>}
Formulaire <form id="form1" runat="server"> <form method="post"> <form @submit.prevent="submitForm"> <form (ngSubmit)="submitForm()" #form="ngForm"> <form onSubmit={handleSubmit}>
Lien <asp:HyperLink NavigateUrl="..." /> <a asp-page="/Contact">Contact</a> <router-link to="/contact">Contact</router-link> <a routerLink="/contact">Contact</a> <Link to="/contact">Contact</Link>
Script intégré <script runat="server">...</script> @{ ... } ou fichier .cshtml.cs <script setup> const msg = "..." </script> Dans component.ts (msg: string = '...') Dans une composante .jsx ou .tsx, exemple : const msg = "..."

Remplacements possibles de Web Forms en ASP.NET Core :

Web Forms Remplacement en ASP.NET Core Description
.aspx pages (Pages événementielles) Razor Pages Plus proche de Web Forms : chaque page a son modèle (code-behind simplifié).
Contrôles serveur (<asp:Label>,...) Tag Helpers / HTML Helpers Syntaxe Razor moderne pour générer du HTML dynamiquement.
CodeBehind avec logique UI Razor Pages avec Handlers OnGet, OnPost,..., pour gérer les requêtes HTTP.
Postback automatique Formulaires HTML + Razor Handlers Tout se fait via formulaires HTML standard et gestion des requêtes explicites.
ViewState Pas de ViewState Utiliser modèles forts (Model Binding) + TempData, Session, ou base de données.
MasterPage (.master) Layouts Razor (_Layout.cshtml) Structure HTML réutilisable avec sections (@RenderBody, @RenderSection).
Events (Button_Click) Form + OnPost Gérer les événements avec des méthodes C# nommées (OnPost, OnPostMyAction,...).
Web Forms GridView Razor avec boucles / Blazor Utiliser des boucles (foreach) ou composants pour l'affichage des listes.

Exemple : remplacement simple d'un bouton Web Forms

Web Forms :

  1. <asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Envoyer" />

Razor Pages :

  1. <form method="post">
  2.     <button type="submit" asp-page-handler="Submit">Envoyer</button>
  3. </form>

et son code C# :

  1. public class IndexModel : PageModel
  2. {
  3.     public void OnPostSubmit()
  4.     {
  5.         // logique ici
  6.     }
  7. }

Découper l'application

Lorsque tu planifies une migration vers ASP.NET Core, le choix de la version de .NET est une étape stratégique. Depuis l'unification de .NET Core et .NET Framework dans .NET 5, puis les versions LTS (Long Term Support) comme .NET 6 et .NET 8, il est recommandé de se baser sur une version LTS pour garantir stabilité et support à long terme. Les versions LTS sont supportées pendant 3 ans, ce qui te permet de travailler sereinement sans craindre des mises à jour majeures tous les six mois. À l'heure actuelle, .NET 8 est la version LTS la plus récente, offrant de meilleures performances, une meilleure sécurité et de nouveaux outils de développement. Migrer vers une version plus ancienne comme .NET 5 ou 6 n'est généralement utile que si des dépendances ou des contraintes techniques l'exigent. Il est donc primordial d'évaluer la compatibilité de tes bibliothèques et outils avec la version cible. Prendre le temps de faire ce choix évite des retours en arrière coûteux.

Ce choix de version a également un impact direct sur les outils de développement que tu vas utiliser, notamment Visual Studio. Par exemple, Visual Studio 2022 prend en charge les versions .NET 6 à 8, tandis que des versions plus anciennes de Visual Studio ne permettent pas toujours de travailler confortablement avec ASP.NET Core. Assurez-vous aussi que ton environnement CI/CD, ton système d'exploitation et tes serveurs sont compatibles avec la version choisie. Certaines versions de Windows Server, par exemple, ne supportent pas correctement .NET 8 sans mises à jour. Si tu prévois d'héberger ton application sur Linux, les versions récentes de .NET Core offrent aussi une meilleure compatibilité et des performances accrues. Le choix de la version va donc bien au-delà de la simple volonté d'utiliser "la dernière". Il doit être réfléchi en fonction de ton infrastructure, de ton équipe et de ton planning.

Choisir une version récente et stable comme .NET 8 permet aussi de bénéficier de toutes les améliorations récentes du cadre d'application. Vous pouvez profiter de fonctionnalités modernes comme les minimal APIs, les performances accrues du ramasse-miettes, ou encore les nouvelles options de sécurité intégrées. Cela rend le code plus propre, plus rapide et plus facile à maintenir. Si ton équipe est déjà familière avec les anciennes versions de .NET Core, la montée en compétence vers les dernières versions ne sera pas trop complexe, car Microsoft a veillé à garder une certaine continuité. En résumé, mieux vaut investir un peu de temps dans la sélection de la bonne version .NET en amont, plutôt que de devoir refaire une migration dans quelques mois pour suivre les mises à jour. C'est une base solide sur laquelle tout le reste du projet va reposer.

ASP.NET Core n'utilise pas System.Web. Il faut donc isoler les dépendances :

Fonctionnalité / Utilisation classique ASP.NET (System.Web) ASP.NET Core (Remplacement) Explication / Détail
Gestion des requêtes HTTP HttpContext.Current HttpContext via l'injection de dépendances Accessible dans les contrôleurs, middlewares,...
Session HttpContext.Current.Session HttpContext.Session (nécessite config DI) Activer via services.AddSession() et app.UseSession()
Cookies Response.Cookies.Add() / Request.Cookies HttpContext.Response.Cookies.Append() Plus clair et mieux structuré
QueryString / Form Request.QueryString, Request.Form HttpContext.Request.Query, Request.Form Accès direct, typé
Redirection Response.Redirect(url) Redirect(url) dans un contrôleur Méthode intégrée des contrôleurs
Filtres (auth, cache,...) ActionFilterAttribute, AuthorizeAttribute Mêmes noms ([Authorize], [ServiceFilter], ...) Le modèle est conservé mais modernisé
Authentication Forms FormsAuthentication CookieAuthentication via AddAuthentication() Plus sécurisé et configurable
Web.config Web.config appsettings.json, appsettings.Development.json Configuration typée, par environnement
Téléversement de fichier Request.Files IFormFile Injection via action (public IActionResult Upload(IFormFile file))
Server.MapPath() Server.MapPath("~/somefile") IWebHostEnvironment.WebRootPath Injecter IWebHostEnvironment
Application State / Cache HttpContext.Application, HttpRuntime.Cache IMemoryCache, IDistributedCache Injection via DI (ex: services.AddMemoryCache())
URL Routing RouteConfig.cs, routes.MapRoute() MapControllerRoute(), MapGet(), endpoint routing Configuration fluide dans Program.cs ou Startup.cs
Server Controls / WebForms Label, Button,... Non supporté ASP.NET Core ne supporte pas WebForms. Migrer vers Razor Pages ou MVC

Migrer étape par étape (si possible)

ASP.NET Core introduit une nouvelle façon d'organiser les projets par rapport à ASP.NET classique. L'arborescence est plus simple et plus modulaire, avec une structure allégée dès la création du projet. Le fichier csproj a été entièrement repensé : il est beaucoup plus lisible, ne nécessite plus de lister chaque fichier source, et intègre par défaut les bonnes pratiques modernes. Le dossier wwwroot remplace l'ancien répertoire Content pour accueillir les fichiers statiques comme les images, CSS ou JavaScript. Le fichier Startup.cs (ou Program.cs selon la version) centralise désormais toute la configuration, ce qui rend l'initialisation plus explicite. Adapter la structure, c'est aussi se débarrasser de ce qui est obsolète : fichiers .aspx, Global.asax, ou Web.config, n'étant plus utilisés. Cela implique un vrai travail de nettoyage pour repartir sur une base saine.

L'une des premières étapes dans cette adaptation consiste à recréer un nouveau projet ASP.NET Core à l'aide d'un gabarit vierge ou standard fourni par Visual Studio ou la CLI (dotnet new). Ensuite, on migre progressivement les fichiers utiles de l'ancien projet vers le nouveau, tout en réorganisant les dossiers selon les conventions modernes (Controllers, Views, Models, Services,...). Ce processus permet de revoir la logique du projet, de simplifier ce qui peut l'être et d'isoler plus clairement les responsabilités. C'est aussi l'occasion d'introduire des pratiques modernes comme l'injection de dépendances, mieux intégrée dans ASP.NET Core. Attention toutefois à ne pas faire de simple "copier-coller" de fichiers : mieux vaut analyser chaque composante pour décider s'il mérite d'être conservé, réécrit ou supprimé.

La nouvelle structure de projet favorise également une meilleure séparation des préoccupations, une meilleure testabilité, et une plus grande évolutivité. Par exemple, en séparant clairement les services métiers, les interfaces, les contrôleurs et les entités, on obtient un projet plus maintenable à long terme. ASP.NET Core vous poussera aussi à externaliser la configuration via appsettings.json plutôt qu'à la coder en dur ou à l'enfermer dans des fichiers XML. En migrant vers cette structure, vous profitez d'un environnement plus cohérent avec les standards modernes de développement. C'est aussi une étape propice pour introduire des outils complémentaires comme MediatR, FluentValidation ou AutoMapper, s'intégrant naturellement dans une architecture bien pensée. Bref, adapter la structure, c'est poser les fondations solides de ta future application.

Vous pouvez utiliser une approche progressive :

Refaire la structure de projet

L'une des étapes cruciales lors de la migration vers ASP.NET Core consiste à mettre à jour les dépendances du projet. Les paquets NuGet utilisés dans ASP.NET classique ne sont pas tous compatibles avec .NET Core ou .NET 6/7/8. Il faut donc identifier ceux étant obsolètes ou remplacés par des alternatives plus modernes. Par exemple, certains paquets liés à System.Web n'existent plus, car ASP.NET Core utilise un pipeline HTTP différent et plus léger. Il est recommandé d'utiliser des outils comme dotnet list package ou NuGet Package Manager pour analyser les dépendances actuelles. Ensuite, on recherche des versions compatibles avec .NET Core, ou des bibliothèques équivalentes maintenues et bien documentées. Cette mise à jour permet également de renforcer la sécurité en se débarrassant des versions vulnérables.

ASP.NET Core encourage l'usage de bibliothèques modernes et optimisées pour les performances. Beaucoup de packages utilisés auparavant ont été intégrés directement dans le cadre d'application ou bien remplacés par des solutions natives. Par exemple, l'authentification, la gestion des cookies ou l'accès à la base de données via Entity Framework Core sont intégrés et mieux conçus. Lors de la mise à jour, c'est une bonne idée de se poser la question suivante pour chaque paquet : «Est-il toujours nécessaire ?» ou «Existe-t-il une alternative native dans ASP.NET Core ?». Il faut aussi penser à la cohérence des versions : un paquet compatible .NET Standard ne l'est pas forcément avec .NET 6 ou 7. Documenter les changements de paquets t'évitera bien des surprises lors du déploiement.

Enfin, la mise à jour des dépendances est l'occasion de renforcer la gouvernance technique du projet. C'est le bon moment pour introduire une gestion de version centralisée, des outils comme Dependabot pour automatiser les mises à jour, ou encore un fichier Directory.Packages.props pour rationaliser les versions de paquets sur plusieurs projets. Il est aussi recommandé d'ajouter des tests de non-régression pour s'assurer que les changements de bibliothèques ne cassent pas des fonctionnalités existantes. Cette démarche préventive évite les régressions silencieuses. À la fin, ton projet est non seulement à jour, mais aussi plus stable, plus sécurisé, et mieux préparé pour évoluer avec les futures versions de .NET.

ASP.NET Core a une autre structure :

Élément / Fichier ASP.NET (Framework) ASP.NET Core Remarques
Fichier de démarrage Global.asax Program.cs, Startup.cs (jusqu'à .NET 6) Startup.cs contient ConfigureServices et Configure. Depuis .NET 6, tout est dans Program.cs.
Fichier de configuration Web.config appsettings.json Plus lisible, extensible, support de multiples environnements.
Routage RouteConfig.cs dans App_Start Configuré dans Program.cs ou Startup.cs Utilise MapControllers, MapGet,...
Config DI (Injection) Aucun / custom ConfigureServices dans Startup.cs ASP.NET Core a une DI intégrée.
Gestion erreurs web.config, Global.asax Middleware dans Startup.cs (UseExceptionHandler,...) Plus modulaire et personnalisable.
Fichiers de journaux de bord Custom / Log4Net.config,... Configuration dans appsettings.json ou via code (Serilog,..) Intégration native de journal de bord extensible.
Dossiers de ressources statiques Content/, Scripts/ wwwroot/ Contient les fichiers accessibles directement par le client.
Assemblage de scripts/styles BundleConfig.cs + Scripts/, Content/ Utilisation de Webpack, Vite,... ou Razor Class Libs Bundling/Minification externe ou dynamique.
Contrôleurs Controllers/ Controllers/ Structure similaire, mais avec ControllerBase ou Controller.
Vues Views/ Views/ Toujours basé sur Razor. Pas de gros changement.
Fichiers modèles Models/ Models/ Pas de changement, mais peuvent inclure DataAnnotations,...
Filtres globaux FilterConfig.cs Dans Startup.cs via services.AddControllers(options => ...) Approche plus centralisée et typée.
Fichier projet .csproj complexe, avec plein de références manuelles .csproj simplifié avec SDK-style Facile à lire, gérer et partager.

Adapter les dépendances et middleware

ASP.NET Core introduit une nouvelle façon de configurer les applications, différant considérablement de l'approche utilisée dans le cadre d'application ASP.NET. Au lieu d'utiliser des fichiers comme Global.asax, Web.config, ou des sections XML, on travaille désormais avec des fichiers C# comme Program.cs et Startup.cs. Ces fichiers permettent une configuration fluide et centralisée de l'application, en utilisant du code clair et fortement typé. La méthode ConfigureServices sert à injecter les services dont l'application a besoin, tandis que Configure permet de définir le pipeline de traitement des requêtes HTTP. Cette nouvelle architecture donne plus de contrôle au développeur et améliore la lisibilité et la modularité du projet.

L'un des grands avantages du pipeline ASP.NET Core est sa flexibilité. On peut y ajouter ou retirer des middlewares très simplement, comme ceux pour la gestion des erreurs, l'authentification, ou le routage. Chaque requête passe par ce pipeline, ce qui permet d'intercepter, modifier ou rediriger les requêtes à différents moments. Contrairement à ASP.NET classique, il n'y a plus de "magie cachée" dans le fonctionnement du cadre d'application : tout est explicite. De plus, l'ordre des middlewares dans la méthode Configure est important, car il détermine la manière dont les requêtes sont traitées. Il est donc essentiel d'analyser son ancienne configuration et de la traduire correctement dans le nouveau modèle ASP.NET Core.

Enfin, la configuration de l'application (paramètres, chaînes de connexion, variables d'environnement,...) se fait généralement via le fichier appsettings.json, beaucoup plus lisible et souple que l'ancien Web.config. Ce fichier peut être complété par des sources comme les variables d'environnement, les secrets utilisateurs, ou même un service distant. Cette hiérarchie permet de gérer proprement les différentes configurations selon l'environnement (développement, production, test). Grâce à la classe IConfiguration, il est très simple d'accéder aux paramètres dans n'importe quelle composante. Cette refonte de la configuration et du pipeline est un gros changement, mais elle rend les applications plus maintenables et prêtes pour les exigences modernes de l'infonuagique et du DevOps.

Dépendance (ASP.NET) Équivalent(s) ou alternative(s) pour ASP.NET Core Remarques
Elmah elmah.io, ElmahCore elmah.io est SaaS, ElmahCore est une adaptation pour ASP.NET Core.
Unity / Ninject / Autofac ASP.NET Core DI natif, Autofac Le système DI intégré est suffisant, mais Autofac reste compatible si besoin de plus d'options.
Log4Net Serilog, NLog, Microsoft.Extensions.Logging Serilog est très populaire avec des sinks pour divers supports.
System.Web.Caching IMemoryCache, IDistributedCache (ASP.NET Core) Fournit des alternatives locales ou distribuées (Redis, SQL Server).
OWIN Middleware Middleware ASP.NET Core (dans Startup.cs) ASP.NET Core utilise une pipeline middleware très flexible.
HttpModule / HttpHandler Middleware ASP.NET Core Toute la logique est intégrée dans la pipeline via app.Use...()
Web.config appsettings.json + IConfiguration Remplacé par un système de configuration flexible basé sur JSON/env/secret store.
FormsAuthentication ASP.NET Core Identity, JWT, Cookie Authentication Supporte plusieurs types d'authentification modernes.
Global.asax (Events) Middleware et Startup.cs Les événements sont remplacés par les méthodes Configure et ConfigureServices.
SignalR (ASP.NET) SignalR for ASP.NET Core SignalR a été réécrit pour ASP.NET Core avec des performances améliorées.
Web API (System.Web.Http) Microsoft.AspNetCore.Mvc Unifié avec MVC dans ASP.NET Core (pas besoin de Web API séparé).
RouteConfig.cs Routage via MapControllerRoute ou MapGet dans Program.cs / Startup.cs Routage plus simple et plus puissant.
Bundles (ScriptBundle) Webpack, Gulp, Vite, ESBuild, ou Razor Class Libraries Plus flexible, support moderne de JavaScript et CSS via outils front-end.

Recréer les routes, contrôleurs, vues (si MVC)

ASP.NET Core repose nativement sur un système d'injection de dépendances (DI) intégré, contrairement à ASP.NET classique nécessitant souvent des bibliothèques tierces comme Unity, Autofac ou Ninject. Cela signifie que dès la création de l'application, le cadre d'application fournit un conteneur léger mais puissant permettant de gérer les dépendances de manière structurée. Ce mécanisme favorise le développement d'applications modulaires, testables et maintenables. Il est commun d'enregistrer ses services dans la méthode ConfigureServices du fichier Startup.cs, en choisissant leur cycle de vie7nbsp;: Singleton, Scoped ou Transient. Cette approche permet de mieux contrôler la gestion de la mémoire et les responsabilités de chaque composante. Elle encourage également les bonnes pratiques de séparation des responsabilités et d'abstraction.

Lorsque l'on migre une application ASP.NET vers ASP.NET Core, il est nécessaire d'adapter la logique de résolution des dépendances existantes. Par exemple, les contrôleurs, services ou repositories doivent être réécrits ou ajustés pour bénéficier de l'injection de dépendances via le constructeur. Il faut également s'assurer que toutes les interfaces nécessaires sont bien enregistrées dans le conteneur. Dans certains cas, on peut réutiliser des bibliothèques tierces si le conteneur par défaut ne répond pas aux besoins spécifiques, mais cela est rarement nécessaire. Le passage à l'injection native améliore la cohérence du code, limite les dépendances externes, et simplifie le déploiement. Cela peut représenter une charge initiale, mais les bénéfices à long terme sont significatifs.

De plus, ASP.NET Core permet également d'injecter facilement des services du cadre d'application lui-même, comme ILogger, IConfiguration, ou IWebHostEnvironment, directement dans les classes métier. Cette capacité renforce l'intégration entre les différents modules et réduit la nécessité d'écrire du code de configuration complexe. Pour les tests unitaires, l'injection de dépendances facilite la création de mocks ou de doubles d'objets, améliorant la qualité du code. Il est donc essentiel, lors d'une migration, d'identifier tous les points de dépendance et de les adapter selon le nouveau paradigme. En fin de compte, cette refonte pousse vers une architecture plus moderne, propre et orientée services, parfaitement alignée avec les principes SOLID.

Les fichiers .cshtml sont très proches entre ASP.NET MVC 5 et Core, mais&nbps;:



Dernière mise à jour : Vendredi, le 6 septembre 2024