Les nouveautés de ASP.NET Core 2.0

Hinault Romaric

Cet tutoriel a pour but de présenter les nouvelles fonctionnalités et améliorations du Framework Web open source ASP.NET Core.

Commentez

- Titre : Les nouveautés de ASP.NET Core 2.0

- Auteur : Hinault Romaric

- Parution : 4 septembre 2017

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2017 Hinault Romaric. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Présentation de ASP.NET Core

- III. Développer avec ASP.NET Core 2.0

- IV. Installer .NET core 2.0

- IV-A. Sous Windows

- IV-B. Sous Linux

- IV-C. Sous Mac

- V. Migrer une application ASP.NET Core existante vers ASP.NET Core 2.0

- V-A. Mise à jour de la version du Framework

- V-B. Mise à jour des packages

- V-C. Mise à jour des outils .NET Core

- V-D. Autres modifications

- VI. Razor Pages

- VII. Les nouveaux templates SPA

- VII-A. Intégration de Webpack

- VII-B. Implémentation du Hot Module Replacement

- VII-C. Server-side prerendering

- VII-D. Structure d'une application SPA ASP.NET Core

- VIII. Le metapackage Microsoft.AspNetCore.All

- VIII-A. .NET Core 2.0 Runtime Store et metapackage Microsoft.AspNetCore.All

- IX. Refactorisation du code du fichier Program.cs

- X. Journalisation

- XI. Autres nouveautés et améliorations

- XI-A. Changements apportés à l'authentification

- XI-B. .NET Standard 2.0

- XI-C. Améliorations apportées à Kestrel

- XI-D. Support de C# 7.1 dans Razor

- XII. Conclusion

- XIII. Remerciements

- XIV. Références

I - Introduction

Microsoft a dévoilé il y a quelques jours la version stable de ASP.NET Core 2.0, sa plateforme de développement Web open source. Il s'agit d'une mise à jour majeure, qui apporte un nombre intéressant de nouvelles fonctionnalités et améliorations.

Cette version permettra aux développeurs de créer et monitorer des applications Web avec beaucoup plus de facilité. Elle offrira également des gains de performances.

Dans ce tutoriel, nous allons faire un tour d'horizon des nouveautés de ASP.NET Core 2.0.

II - Présentation de ASP.NET Core

ASP.NET Core est une jeune plateforme de développement, dont la première version stable à vue le jour en juin 2016. Elle a été créée pour répondre aux besoins des développeurs dans la mise en place d'applications Web modernes multiplateformes pouvant cibler le cloud et le mobile.

ASP.NET Core a donc été développé avec à l'esprit l'ouverture, les performances et la légèreté :

- le Framework est développé en open source avec la participation de la communauté. Son code source est disponible sur GitHub ;

- il est multiplateforme et peut fonctionner sur Windows, Linux et Mac ;

- il est indépendant de tout environnement de développement. Pas besoin de Visual Studio pour créer une application ASP.NET Core ;

- il est développé autour de la modularité. De ce fait, une application ASP.NET Core est publiée uniquement avec le nécessaire pour son fonctionnement. Ce qui rend la plateforme un candidat de choix pour le cloud, où l'espace de stockage utilisé est facturé.

III - Développer avec ASP.NET Core 2.0

Pour créer des applications ASP.NET Core 2.0, vous devez installer le Framework .NET Core 2.0 et le SDK (Software Development Kit) pour .NET  Core 2.0.

Vous n'avez pas besoin d'un éditeur particulier pour créer des applications ASP.NET Core. Le SDK offre un outil en ligne de commande (CLI - Command-line interface) permettant de créer, générer, exécuter et publier une application.

Toutefois, il existe sur le marché les environnements de développement suivants qui offrent une bonne prise en charge de  ASP.NET Core 2.0 :

- Visual Studio 2017 Update 3 ;

- Visual Studio Code ;

- JetBrains Rider 20017.1.

Pour les exemples de code de cet article, je vais utiliser Visual Studio Code ou Visual Studio 2017 Update 3, édition Community.

IV - Installer .NET core 2.0

.NET Core 2.0 est disponible pour Windows, Linux, OS X et comme image Docker. Il s'installe side by side avec les versions précédentes de .NET Core.

IV-A - Sous Windows

Pour installer la plateforme sous Windows, vous pouvez la télécharger à l'adresse suivante : https://www.microsoft.com/net/core#windowscmd.

L'installation est une succession de clics.

IV-B - Sous Linux

Pour installer .NET Core 2.0 sous un système d'exploitation Ubuntu, vous devez exécuter la commande suivante :

sudo apt-get install dotnet-sdk-2.0.0

Mais avant, vous devez ajouter dotnet à votre apt-get feed. C'est l'emplacement où est hébergé le package. Le lien varie d'une version à l'autre d'Ubuntu. Pour plus de détails, veuillez consulter le lien suivant : https://www.microsoft.com/net/core#linuxubuntu

Vous aurez également des indications pour l'installer sur RedHat, Debian, Fedora, CentOS, Oracle Linux et openSUSE.

IV-C - Sous Mac

Pour installer la plateforme sous Mac OS X, vous devez télécharger le package d'installation à l'adresse suivante : https://www.microsoft.com/net/core#macos.

L'installation est une succession de clics.

Pour vérifier que votre installation s'est effectuée correctement, vous devez utiliser la commande suivante en invite de commande :

dotnet --version :

V - Migrer une application ASP.NET Core existante vers ASP.NET Core 2.0

V-A - Mise à jour de la version du Framework

Pour migrer votre application sous ASP.NET Core 1.x vers ASP.NET Core 2.0, la première chose à faire sera d'éditer le fichier .csproj et modifier la version du Framework qui est utilisée.

La section suivante :

<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>

doit être modifiée en :

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

Si vous ciblez le Full Framework .NET dans votre projet, vous devez modifier sa version pour utiliser une version supérieure ou égale à 4.6.1. Il est référencé dans la section TargetFramework. Vous allez désormais avoir ceci :

<TargetFramework>net461</TargetFramework>

Si vous utilisez Visual Studio, vous pouvez simplement aller dans les propriétés du projet, et cliquer sur la zone déroulante « Target Framework », puis choisir .NET Core 2.0.

V-B - Mise à jour des packages

Une fois cela fait, vous devez faire passer tous les packages ASP.NET Core (Microsoft.AspNetCore.xxx) qui sont référencés dans votre projet vers les nouvelles versions de ceux-ci. Vous pouvez également modifier les packages pour EntityFramework Core vers la version 2.0 qui a été publiée au même moment.

Pour mon application dont les packages suivants sont référencés :

<ItemGroup>
<PackageReference Include="BuildBundlerMinifier" Version="2.4.337" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.0.3" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SQLite" Version="1.0.*" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.0.*" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools.Dotnet" Version="1.0.0" />
</ItemGroup>

je vais obtenir le résultat suivant après mise à jour :

<ItemGroup>
<PackageReference Include="BuildBundlerMinifier" Version="2.4.337" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SQLite" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools.Dotnet" Version="2.0.0" />
</ItemGroup>

Vous pouvez migrer vos packages encore plus simplement, en remplaçant ceux-ci par une référence unique au metapackage Microsoft.AspNetCore.All comme suit :

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
</ItemGroup>

Il s'agit d'une nouveauté de ASP.NET Core 2.0. Nous y reviendrons de façon un peu plus détaillée dans les parties suivantes.

V-C - Mise à jour des outils .NET Core

Dans le fichier .csproj, il pourrait également exister une section dans laquelle sont référencés les outils CLI .NET Core. Ils sont notamment utilisés pour la génération de code ou par EntityFramework pour la génération des bases de données.

<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
</ItemGroup>

Vous devez également les modifier pour cibler .NET Core 2.0 :

<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>

V-D - Autres modifications

Le fichier Program.cs a été refactorisé dans ASP.NET Core 2.0. Pour éviter les potentiels problèmes que pourrait causer le code de la version avec ASP.NET Core 1.x, je vous recommande de modifier le code de votre classe Program.cs pour utiliser celui proposé avec ASP.NET Core 2.0.

Vous devez donc éditer votre fichier Program.cs et remplacer le code suivant :

public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();

host.Run();
}
}

par :

public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}

Si dans votre fichier .csproj, vous avez la section PackageTargetFallBack :

<PackageTargetFallback>portable-net45+win8</PackageTargetFallback>

elle doit être renommée en AssertTargetFallback :

<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>

VI - Razor Pages

L'utilisation du modèle MVC oblige le développeur à adopter un pattern dans la mise en place de son application. Ce découpage impose l'utilisation de nombreux fichiers. Pour une petite application, l'utilisation du modèle MVC entraîne plus d'effort et impose la maîtrise d'ASP.NET Core MVC.

Pour les développeurs qui veulent mettre en place de petites applications Web sans avoir à faire face aux contraintes architecturales qu'impose MVC, Razor Pages est désormais offert avec ASP.NET Core 2.0. Razor Pages peut également être pratique pour les débutants ou les développeurs qui ont précédemment utilisé ASP.NET WebForms.

Razor Pages offre un modèle de programmation permettant d'inclure dans un fichier .cshtml du code HTML, CSS, JavaScript et C# pour produire une page Web, sans avoir recours à un contrôleur comme avec MVC.

Razor Pages existait déjà sous ASP.NET. Ce dernier avait été introduit avec l'IDE WebMatrix, sous le nom de WebPages. Toutefois, Razor Pages était disponible séparément tout comme WebForms, MVC et Web API. Dans ASP.NET Core, MVC et WebAPI ont été fusionnés. C'est également le cas avec Razor Pages.

Le package Microsoft.AspNetCore.Mvc permet d'exploiter toutes les fonctionnalités de Razor Pages. Toutefois, elles sont disponibles dans l'espace de nommage Microsoft.AspNetCore.Mvc.RazorPages.

Après avoir installé ASP.NET Core 2.0 et Visual Studio 2017 Update 3, vous verrez un nouveau modèle de projet pour Razor Pages dans la liste des templates :

Si vous ne disposez pas de Visual Studio, le nouveau modèle est également disponible dans les templates des outils de développement pour .NET Core. Pour créer un nouveau projet Razor Pages, il suffit d'utiliser la commande suivante :

Dotnet new razor -n NomProjet

La structure d'une application Razor Pages est très différente de celle d'une application MVC, comme vous pouvez le constater avec la capture ci-dessous :

Nous n'avons pas de dossier Controllers ni de dossier Views. Nous avons juste un dossier Pages, avec des vues Razor.

Un fichier Razor Pages commence avec l'instruction suivante :

@page

Pour séparer le contenu de présentation de la logique métier, Razor Pages offre l'instruction @functions :

@page

@functions{

public string Message { get; set; }

public void OnGet()
{
Message = "Your application description page.";
}

}

@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@Message</h3>

<p>Use this area to provide additional information.</p>

Le code ci-dessus, avant le rendu de la page, va exécuter au préalable la méthode OnGet(). Razor Pages apporte une convention pour exécuter les méthodes (action) en fonction des requêtes HTTP. Ainsi, pour une requête HTTP Get sur une Razor Pages, la fonction OnGet dans le code de cette page sera automatiquement exécutée. Pour une requête Post, la fonction OnPost() sera exécutée.

Pour permettre une meilleure séparation du code, Razor Pages introduit la notion de PageModel. Au lieu d'avoir une seule page About.cshtml, nous aurons également une page About.cshtml.cs, qui va contenir la classe AboutModel, qui hérite de PageModel.

Dans cette page, nous aurons le code-behind de notre page :

public class AboutModel: PageModel
{
public string Message { get; set; }

public void OnGet()
{
Message = "Your application description page.";
}
}

Et le contenu de la page About.cshtml devient ceci :

@page
@model AboutModel
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@Model.Message</h3>
<p>Use this area to provide additional information.</p>

Le contenu des fichiers Program.cs et Startup.cs reste identique avec un projet MVC.

VII - Les nouveaux templates SPA

JavaScript est devenu un langage quasi incontournable pour le développement d'applications Web. Il existe de nombreux frameworks et des implémentations permettant de combler certaines faiblesses de JavaScript, et qui rendent le langage encore plus attrayant. Ceux qui jouissent d'une grosse popularité sont à ce jour :

- TypeScript : un sur-ensemble typé de JavaScript développé par Microsoft. Il apporte entre autres, un typage statique et optionnel, un système de classes et d'interfaces, une division en modules, la gestion de l'importation de fichiers, la prise en charge des génériques et bien plus ;

- AngularJS : développé par Google, AngularJS est un framework de développement Web basé sur TypeScript (depuis la version 4.0). Sa particularité est qu'il offre un modèle de programmation fondé sur de bonnes pratiques, dont l'architecture MVC, le DataBinding, ou encore l'injection de dépendances. AngularJS est actuellement l'un des frameworks JavaScript les plus prometteurs ;

- ReactJS : il s'agit d'une bibliothèque JavaScript open source maintenue par le géant des réseaux sociaux Facebook. La particularité de ReactJS est qu'il permet « la création d'applications web monopages, via la création de composants dépendants d'un état et générant une page (ou portion) HTML à chaque changement d'état ».

Pour séduire encore plus de développeurs, ASP.NET Core 2.0 introduit de nouveaux modèles de projet pour Angular et ReactJS. Ces nouveaux modèles permettent de créer rapidement une application ASP.NET Core, avec ces bibliothèques directement intégrées et des outils comme WebPack automatiquement configurés.

Si vous disposez de Visual Studio 2017 Update 3, dans la fenêtre de création d'une nouvelle application ASP.NET Core 2.0, vous verrez, les nouveaux modèles de projet :

Ces nouveaux modèles de projet vont permettre de créer des applications SPA (Single Page Application) avec :

- ASP.NET Core et AngularJS ;

- ASP.NET Core et ReactJS ;

- ASP.NET Core, ReactJS et Redux.

Les applications SPA ont comme particularité l'affichage de l'ensemble du contenu de l'application sans nécessiter le chargement d'une page à chaque action. C'est pourquoi elles s'appuient grandement sur les bibliothèques JavaScript comme Angular et React.

Les nouveaux modèles d'applications ASP.NET Core combinent plusieurs éléments permettant aux développeurs de gagner en performance et d'améliorer la réactivité des applications.

VII-A - Intégration de Webpack

Tous ces modèles utilisent Webpack comme système de Build front-end. Les développeurs de ASP.NET Core ont opté pour ce dernier parce qu'il s'agit du système de build le plus populaire chez les développeurs Angular et React.

Webpack rend la vie plus facile aux développeurs front-end, en offrant un système de bundler pour les ressources statistiques (fichiers JavaScript, CSS, SVG, PNG, etc.). Celles-ci sont transformées par Webpack et consommées dans votre application comme des modules. Pendant le développement de votre application, Webpack s'exécute en continu en arrière-plan et, lorsqu'un fichier est modifié, il procède automatiquement à la recompilation et rend immédiatement les modifications disponibles au navigateur. Vous n'avez donc pas besoin d'exécuter manuellement une quelconque commande pour builder votre code TypeScript ou Angular après modification.

Ces nouveaux modèles de projet sont configurés de telle sorte qu'en environnement de développement, Webpack build les différents Assets en intégrant les source maps pour faciliter le débogage. Lorsque vous serez prêt à générer votre application pour la production, il vous suffira de switcher en mode Production, pour que Webpack build et génère du code minifié sans inclure les sources maps.

VII-B - Implémentation du Hot Module Replacement

Le Hot Module Replacement (HMR) rend Webpack encore plus intéressant. En effet, à chaque modification de code JavaScript, par exemple, Webpack compile et rend la modification disponible via une mise à jour incrémentale. Toutefois, il faut recharger la page complètement pour que la mise à jour soit prise en compte. Avec HMR, les modifications sont directement transférées au navigateur. Vous verrez celles-ci dans votre page, sans que cette dernière ne soit réactualisée dans le navigateur : seule la portion de la page affectée par le module qui a été modifié est rechargée dans le navigateur.

Cette fonctionnalité permet donc au développeur d'être plus productif et de déboguer son application un peu plus rapidement. Pour voir cette fonctionnalité en action, il vous suffit de modifier un fichier dans le dossier ClientApp, pendant que votre application est en cours de débogage/exécution, pour visualiser instantanément les modifications.

VII-C - Server-side prerendering

Le prérendu côté serveur (Server-side prerendering) a pour but de rendre plus rapide le rendu de l'interface utilisateur côté client. En effet, lors du premier chargement de l'application, le navigateur doit télécharger et exécuter les scripts JavaScript avant le rendu initial de la page. La présence des bibliothèques JavaScript costaudes, à l'instar d'Angular, rallonge encore un peu plus ce temps de chargement et de rendu des pages. Il s'agit même de l'un des plus gros défauts de ces bibliothèques.

Avec le prérendu côté serveur, les composants Angular, par exemple, sont directement exécutés côté serveur. Il est intéressant de noter qu'avec cette fonctionnalité, une application SPA ASP.NET Core peut s'exécuter correctement, même si l'exécution du JavaScript est désactivée dans le navigateur. De plus, l'application est directement optimisée pour les utilisateurs ayant des connexions lentes.

VII-D - Structure d'une application SPA ASP.NET Core

Les applications SPA ASP.NET Core ont quasiment la même structure que les applications ASP.NET Core traditionnelles, à l'exception de l'ajout d'un dossier ClientApp. C'est ce dossier qui doit contenir l'ensemble de votre code Angular/React et dans lequel vous devez créer vos components et services. À la compilation, le code de ce dossier est regroupé dans le fichier main.js du dossier wwwroot/dist.

Il existe également des fichiers de configuration supplémentaires comme le fichier webpack.config.js pour la configuration du comportement de Webpack.

Comme dans une application ASP.NET Core MVC traditionnelle, vous avez le dossier Controllers pour vos contrôleurs et le dossier Views pour vos fichiers .cshtml.

Il faut noter que ces modèles de projet ne sont pas uniquement disponibles avec Visual Studio. ASP.NET Core a été conçu pour être indépendant de tout environnement de développement. De ce fait, les modèles de projet sont directement intégrés dans le SDK.

En ligne de commande, si vous exécutez la commande dotnet new -all, vous verrez les nouveaux modèles de projet avec le Tag Web/MVC/SPA.

Avec ces nouveaux modèles de projet, ASP.NET Core pourra séduire encore un plus grand nombre de développeurs. Ces derniers n'auront plus besoin de se lancer dans des configurations ardues pour intégrer les bibliothèques JavaScript et les composants nécessaires à la mise en place d'une application SPA.

VIII - Le metapackage Microsoft.AspNetCore.All

ASP.NET Core est bâti autour de la modularité. Les fonctionnalités du Framework sont reparties à travers des packages qui sont disponibles via le gestionnaire de packages NuGet. Ainsi, le développeur peut intégrer à son application juste les composants du Framework dont il a réellement besoin.

Dans la version précédente du Framework, le projet Web de base, par exemple, n'intègre que le package Microsoft.AspNetCore, qui est le minimum nécessaire pour exécuter une application ASP.NET Core. Si dans votre application, vous avez besoin des fonctionnalités supplémentaires pour, par exemple, supporter MVC ou gérer l'authentification, vous devez ajouter les packages correspondants à votre application.

Un développeur expérimenté n'aura pas de problème à le faire. Mais, pour un débutant, l'ajout, la mise à jour ou la suppression des packages peuvent être une source de frustration.

C'est pour offrir plus de souplesse dans la gestion des packages que les développeurs de .NET Core ont introduit le metapackage Microsoft.AspNetCore.All. Il offre une option à ceux qui ne veulent pas s'importuner avec la gestion des packages dans leur projet.

À la création d'une nouvelle application avec ASP.NET Core 2.0, l'unique package référencé est Microsoft.AspNetCore.All :

<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
</ItemGroup>

<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>

</Project>

Il s'agit d'un metapackage permettant de référencer dans son projet tous les packages NuGet nécessaires à l'exécution d'une application ASP.NET Core. On y retrouve notamment les packages pour l'authentification, Razor, le monitoring, Kestrel, etc. Les packages pour EntityFramework Core et de nombreuses autres extensions y sont également inclus.

À ce stade, la question que vous vous posez probablement est de savoir comment ces dépendances sont gérées au moment de déployer son application. En effet, si toutes les dépendances sont incluses dans le package de déploiement, on perd l'un des gros intérêts de la modularité de ASP.NET Core : la possibilité de déployer une application moins volumineuse avec uniquement les packages nécessaires à son fonctionnement. Sur ce point, .NET Core a été développé de telle sorte que le package de déploiement d'une application n'inclura que les packages qui ont été utilisés dans le code de l'application.

VIII-A - .NET Core 2.0 Runtime Store et metapackage Microsoft.AspNetCore.All

La nouveauté .NET Core 2.0 Runtime Store rend le metapackage Microsoft.AspNetCore.All encore plus intéressant. Ce dernier s'appuie sur cette fonctionnalité pour offrir de meilleures performances.

En effet, .NET Core est désormais livré avec un Runtime Store. Le Runtime Store embarque tous les packages nécessaires à l'exécution d'une application ASP.NET Core. L'aspect intéressant de cette galerie est le fait que tous les packages sont déjà précompilés en code natif.

Le store est contenu dans le dossier Program Files\dotnet\store :

Comme vous pouvez le constater, les packages ASP.Net Core sont inclus par défaut.

Les applications utilisant Microsoft.AspNetCore.All vont automatiquement profiter de cette nouveauté. Les applications n'ont plus besoin d'être publiées et déployées avec l'ensemble des packages nécessaires à leur fonctionnement. Ce qui entraîne une réduction de la taille du package de déploiement d'une application ASP.NET Core 2.0. La précompilation en code natif de ces packages rend également plus rapide le temps de chargement des applications.

En plus, lors de la publication des applications, la précompilation des vues Razor est automatiquement activée. Ainsi, toutes les vues de l'application seront précompilées dans un assembly. Ce qui permettra également de réduire de façon drastique la taille du package de déploiement et le temps de démarrage de l'application.

IX - Refactorisation du code du fichier Program.cs

Dans la version précédente, le fichier Program.cs avait les lignes de code suivantes :

public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();

host.Run();
}

Si vous ouvrez le fichier Program.cs d'une application ASP.NET Core 2.0, vous remarquerez que ce code a été simplifié :

public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}

La portion de code qui attire l'attention et dont la syntaxe semble un peu superflue est la suivante :

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();

Dans la mesure où le corps de la fonction BuildWebHost ne contient qu'une seule instruction avec le Return, les développeurs de ASP.NET Core ont utilisé une nouveauté de C# 6 appelée « expression-bodied members » (je préfère m'abstenir de fournir une traduction), qui utilise une flèche comme on le fait avec une expression lambda pour introduire le corps de la méthode. Sans l'utilisation de cette fonctionnalité, le code de cette méthode aurait ressemblé à ceci :

public static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}

Vous remarquerez également que lors de l'initialisation de l'hôte (Host), nous n'avons plus les lignes de code permettant de spécifier le serveur Web qui sera utilisé (UseKestrel()), ou encore de spécifier le répertoire racine de l'application (UseContentRoot(Directory.GetCurrentDirectory())).

À la place, nous avons la méthode CreateDefaultBuilder, qui permet de faire cela, en plus d'autres choses. Le code de la classe WebHost est disponible sur GitHub, pour les plus curieux.

Ci-dessous le code de CreateDefaultBuilder :

public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;

config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}

config.AddEnvironmentVariables();

if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});

return builder;
}

Ce code permet de :

- définir Kestrel comme serveur Web ;

- définir le répertoire racine de l'application ;

- charger les éléments de configuration qui sont définis dans le fichier appsettings.json (il est donc important de respecter cette convention). Cette étape était précédemment effectuée dans le fichier Startup.cs ;

- procéder à la configuration de ILoggerFactory pour la journalisation de votre application (ce qui se faisait précédemment dans le fichier Startup.cs) ;

- activer IISIntegration et bien plus.

Les développeurs de ASP.NET Core ont opté pour ce choix parce que la configuration d'une application ASP.NET Core est assez standard et ne varie pas beaucoup d'une application à une autre. De plus, cela réduit le risque d'apporter accidentellement des changements qui pourraient briser la configuration standard. Grâce à cette nouvelle implémentation fournie par CreateDefaultBuilder, le fichier Startup.cs devient :

public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}

Vous remarquerez, par exemple, la suppression des lignes de code permettant de charger le fichier de configuration, de prendre en compte les variables d'environnement, etc.

En déportant la configuration dans la méthode CreateDefaultBuilder, le code des fichiers Program.cs et Startup.cs est désormais beaucoup plus simple.

X - Journalisation

Une autre amélioration de ASP.NET Core 2.0 est la configuration de la journalisation. La méthode Configure() de la classe Startup ne prend plus en paramètre un ILoggerFactory pour injecter dans le pipeline HTTP le middleware pour la journalisation.

La journalisation est désormais intégrée par défaut dans le système d'injection de dépendances. La configuration de la journalisation se fait dans la méthode CreateDefaultBuilder() qui ajoute les modes Console et Debug. Ce qui est intéressant, c'est l'utilisation du fichier appsettings.json pour la configuration de la journalisation :

"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
}
}

XI - Autres nouveautés et améliorations

XI-A - Changements apportés à l'authentification

ASP.NET Core apporte un nouveau modèle d'authentification qui en facilite la configuration pour les applications qui utilisent l'injection de dépendances.

Dans ASP.NET Core 1.0, pour mettre en place l'authentification par Cookie, par exemple, il fallait injecter et configurer le middleware correspondant dans le Startup.cs :

app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AccessDeniedPath = "/Account/Forbidden/",
AuthenticationScheme = "MyCookieAuthenticationScheme",
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = "/Account/Unauthorized/"
});

Avec ASP.NET Core 2.0, vous devez le faire en utilisant simplement ConfigureServices :

services.AddAuthentication("MyCookieAuthenticationScheme")
.AddCookie(options => {
options.AccessDeniedPath = "/Account/Forbidden/";
options.LoginPath = "/Account/Unauthorized/";
});

En plus de cette amélioration, des modifications ont été apportées au gestionnaire d'identité de ASP.NET Core 2.0, afin de rendre plus simple la création des Web API sécurisées en utilisant Identity.

XI-B - .NET Standard 2.0

Les packages ASP.NET Core ciblent .NET Standard 2.0. De ce fait, les packages peuvent être référencés dans d'autres bibliothèques .NET Standard et s'exécuter avec tout Framework qui implémente .NET Standard 2.0, y compris .NET Core 2.0 et .NET Framework 4.6.1.

XI-C - Améliorations apportées à Kestrel

Le serveur Web Kestrel a eu droit à quelques nouvelles fonctionnalités afin d'être meilleur dans les situations où il sert d'interface directe avec Internet (absence d'un serveur Web intermédiaire comme Nginx ou IIS). Dans la configuration de Kestrel, les développeurs peuvent désormais définir des limites pour :

- le nombre de connexions clients maximal ;

- la taille maximale d'une requête ;

- etc.

XI-D - Support de C# 7.1 dans Razor

Le moteur de vue Razor a été mis à jour afin d'offrir une prise en charge du nouveau compilateur Roslyn. Ce qui permet à ce dernier de supporter les nouvelles fonctionnalités de C# 7.1. Pour utiliser les nouveautés de cette version du langage de programmation dans vos vue Razor, vous devez ajouter la propriété suivante dans votre fichier .csproj :

<LangVersion>latest</LangVersion>

XII - Conclusion

Le développement et la publication de ASP.NET Core 2.0 a été rendu possible grâce à la participation de nombreux développeurs indépendants. Le développement du Framework en open source a insufflé une dynamique de travail très différente de celle d'ASP.NET classique. Ce qui permet de livrer plus rapidement de nouvelles fonctionnalités. Au grand bonheur des développeurs.

XIII - Remerciements

Je tiens à remercier François Dorin pour sa relecture technique et jacques_jean pour sa relecture orthographique.

XIV - Références

- Announcing ASP.NET Core 2.0 ;

- ASP.NET Core 2.0 release notes;

- Migrating from ASP.NET Core 1.x to ASP.NET Core 2.0 ;

- ASP.NET Core 2.0 release notes on GitHub ;

- Les nouveautés de ASP.NET Core 2.0 Preview 1 - Part 1 : découverte du metapackage Microsoft.AspNetCore.All ;

- Les nouveautés de ASP.NET Core 2.0 Preview 1 - Partie 2 : Program.cs et CreateDefaultBuilder ;

- Les nouveautés de ASP.NET Core 2.0 Preview - Partie 3 : Introduction à Razor Pages ;

- Les nouveautés de ASP.NET Core Preview partie 4 : les nouveaux templates SPA.