Concrètement, les Areas vont permettre d’avoir une séparation entre les grands modules de votre site Web. Ainsi, pour chaque module, vous allez regrouper dans le même dossier les contrôleurs, vues et modèles correspondants. Pour plus de détail sur les Areas et leur utilisation, vous pouvez consulter mon billet de blog sur le sur sujet.
Dans mon billet précédent, j’ai pris l’exemple d’une entreprise qui avait deux activités principales (vente et réparation) et un espace dédié à l’administration. Dans ce cas de figure, il peut être pratique d’utiliser des sous-domaines pour mieux dissocier les différentes activités.
De ce fait, pour chaque sous-domaine, il faudra diriger l’utilisateur vers l’Area correspondant. Par exemple, si l’utilisateur saisit http://admin.testapp.com/, l’Area admin sera affiché, qui est accessible via l’adresse http://testapp/admin/.
Dans ce billet de blog, nous verrons comment mettre cela en place dans une application ASP.NET en utilisant les middlewares.
Description des middlewares
Le pipeline ASP.NET Core (cycle de vie d’une requête HTTP) regroupe un ensemble d’actions qui sont exécutées suite à une requête et la réponse qui est retournée. Chaque action avec ASP.NET Core va représenter un middleware. Les middlewares sont exécutés de façon séquentielle. Une fois qu’un middleware est exécuté, il passe la main au suivant.
Un middleware peut par exemple s’occuper du chargement du contenu statique, un autre de la sécurité, etc. Les middlewares utilisés par défaut par ASP.NET sont définis dans la méthode Configure du Startup.cs :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute(name: "areaRoute", template: "{area:exists}/{controller=Home}/{action=Index}"); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}"); }); } |
Le middleware app.UseDeveloperExceptionPage(), par exemple, va entrer en action lorsqu’une exception sera levée lors du débogage de votre application et affichera la page d’exception pour les développeurs.
Nous allons donc utiliser un middleware personnalisé pour injecter une action dans le pipeline d’ASP.NET Core. Ce middleware va permettre de réécrire notre URL afin qu’il respecte notre table de routage, avant de passer la main au middleware MVC (app.UseMvc), qui va se charger du routage.
Pour mettre en place ce dernier, nous allons dans un premier temps ajouter une classe AreaRoutingMiddleware. Cette classe doit avoir un constructeur qui prend en paramètre la prochaine RequestDelegate et doit disposer d’une méthode Invoke.
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class AreaRoutingMiddleware { private readonly RequestDelegate _next; public AreaRoutingMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { } } |
Dans la méthode Asynchrone Invoke, nous allons écrire le code permettant de vérifier la présence du nom de l’area dans le nom d’hôte pour ensuite modifier l’URL pour qu’elle soit conforme avec le Template de routage pour les Areas. Le code de cette méthode est le suivant :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public async Task Invoke(HttpContext context) { var host = context.Request.Host.Value; var index = host.IndexOf("."); var subdomains = new string[] { "admin", "vente", "reparation" }; if (index > 0) { var subdomain = host.Substring(0, index); if (subdomains.Contains(subdomain)) { context.Request.Path = "/" + subdomain + context.Request.Path; } } await _next.Invoke(context); } |
Ceci fait, nous allons ajouter une nouvelle classe AreaRoutingExtensions a notre projet, avec le code suivant :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 | public static class AreaRoutingExtensions { public static IApplicationBuilder UseAreaRouting(this IApplicationBuilder builder) { return builder.UseMiddleware<AreaRoutingMiddleware>(); } } |
Ce code permettra d’ajouter notre Middleware personnalisé au pipeline. Maintenant, pour qu’il soit pris en compte et à quel moment, nous devons, l’appeler dans la méthode Configure() du Startup.cs. Puisque nous voulons qu’il soit exécuté avant l’appel du middleware MVC, nous allons l’ajouter avant app.UseMvc :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | app.UseAreaRouting(); app.UseMvc(routes => { routes.MapRoute(name: "areaRoute", template: "{area:exists}/{controller=Home}/{action=Index}"); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}"); }); |
ET lorsque nous allons saisir http://admin.testapp.com/ dans le navigateur, nous aurons :
Pour http://vente.testapp.com/ :