{"id":520,"date":"2022-10-03T07:25:06","date_gmt":"2022-10-03T07:25:06","guid":{"rendered":"https:\/\/oussamasaidi.com\/?p=520"},"modified":"2025-12-20T11:15:10","modified_gmt":"2025-12-20T11:15:10","slug":"automapper-net-core","status":"publish","type":"post","link":"https:\/\/oussamasaidi.com\/en\/automapper-net-core\/","title":{"rendered":"Premiers pas avec AutoMapper dans ASP.NET Core"},"content":{"rendered":"<p>Dans cet article, nous allons apprendre \u00e0 utiliser AutoMapper dans une application ASP.NET Core .<\/p>\n\n\n\n<p>Nous allons commencer par examiner ce qu&rsquo;est AutoMapper et quel probl\u00e8me il r\u00e9sout. Ensuite, nous allons expliquer comment nous pouvons utiliser AutoMapper dans notre application MVC. Apr\u00e8s cela, nous en apprendrons davantage sur les directives d&rsquo;utilisation et les meilleures pratiques. Nous examinerons \u00e9galement ce qui se passe dans les coulisses et comment aplatir des mod\u00e8les d&rsquo;objets complexes.<\/p>\n\n\n\n<p>Table des mati\u00e8res<\/p>\n\n\n<ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-quest-ce-quautomapper\">Qu&#039;est-ce qu&#039;AutoMapper ?<\/a><ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-un-cas-dutilisation\">Un cas d&#039;utilisation d&#039;AutoMapper<\/a><\/li><\/ul><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-comment-utiliser-automapper-dans-notre-application\">Comment utiliser AutoMapper dans notre application<\/a><ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-installation\">Installation d&#039;AutoMapper<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-configuration\">Configuration d&#039;AutoMapper<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-usage\">Usage<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-profils\">Profils<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-mappage-vers-des-proprietes-avec-des-noms-differents\">Mappage vers des propri\u00e9t\u00e9s avec des noms diff\u00e9rents<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-cartographie-inversee\">Cartographie invers\u00e9e<\/a><\/li><\/ul><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-dans-les-coulisses\">Dans les coulisses d&#039;AutoMapper<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-consignes-dutilisation-et-bonnes-pratiques\">Consignes d&#039;utilisation et bonnes pratiques d&#039;AutoMapper<\/a><ul><li><a class=\"aioseo-toc-item\" href=\"#aioseo-a-faire\">\u00c0 faire<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-a-ne-pas-faire\">A ne pas faire<\/a><\/li><\/ul><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-aplatir-des-modeles-dobjets-complexes\">Aplatir des mod\u00e8les d&#039;objets complexes dans AutoMapper<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-conclusion\">Conclusion<\/a><\/li><li><a class=\"aioseo-toc-item\" href=\"#aioseo-derniers-articles\">Derniers Articles<\/a><\/li><\/ul>\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-quest-ce-quautomapper\">Qu&rsquo;est-ce qu&rsquo;AutoMapper ?<\/h2>\n\n\n\n<p>Tout d&rsquo;abord AutoMapper est une biblioth\u00e8que simple qui nous aide \u00e0 transformer un type d&rsquo;objet en un autre. Il s&rsquo;agit d&rsquo;un mappeur d&rsquo;objet \u00e0 objet bas\u00e9 sur des conventions qui n\u00e9cessite tr\u00e8s peu de configuration.&nbsp;<\/p>\n\n\n\n<p>Le mappage objet \u00e0 objet fonctionne en transformant un objet d&rsquo;entr\u00e9e d&rsquo;un type en un objet de sortie d&rsquo;un type diff\u00e9rent.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-un-cas-dutilisation\">Un cas d&rsquo;utilisation d&rsquo;AutoMapper <\/h3>\n\n\n\n<p>AutoMapper a \u00e9t\u00e9 con\u00e7u pour r\u00e9soudre un probl\u00e8me complexe auquel la plupart des d\u00e9veloppeurs sont confront\u00e9s dans leur vie quotidienne : \u00e9crire du code qui mappe un type d&rsquo;objet \u00e0 un autre. Ce type de code est plut\u00f4t fastidieux et ennuyeux \u00e0 \u00e9crire, alors pourquoi ne pas laisser ce travail \u00e0 ce petit outil ?<\/p>\n\n\n\n<p>Ce qui rend AutoMapper int\u00e9ressant, c&rsquo;est qu&rsquo;il fournit des conventions faciles \u00e0 utiliser pour simplifier la t\u00e2che consistant \u00e0 d\u00e9terminer comment mapper  <code>Type A<\/code> vers <code>Type B<\/code>. Tant qu&rsquo;il <code>Type B <\/code>suit les conventions \u00e9tablies d&rsquo;AutoMapper, presque aucune configuration n&rsquo;est n\u00e9cessaire pour mapper deux types.<\/p>\n\n\n\n<p>Voici un sc\u00e9nario courant. Nous avons cr\u00e9\u00e9 une application et nous souhaitons conserver la s\u00e9paration entre nos mod\u00e8les de domaine et nos mod\u00e8les de vue.&nbsp;<\/p>\n\n\n\n<p>Pour ce faire, nous devons \u00e9crire le code pour adapter notre mod\u00e8le de domaine \u00e0 notre mod\u00e8le de vue. Ensuite, \u00e0 mesure que nous ajoutons plus de vues et de mod\u00e8les de domaine, nous finissons par \u00e9crire plus d&rsquo;adaptateurs. Plus tard, nous devrons \u00e9crire encore plus d&rsquo;adaptateurs pour mapper nos objets de transfert de donn\u00e9es de la couche de base de donn\u00e9es dans nos objets de domaine.&nbsp;<\/p>\n\n\n\n<p>C&rsquo;est banal et r\u00e9p\u00e9titif.&nbsp;Et c&rsquo;est l\u00e0 <code>AutoMapper<\/code> qu&rsquo;intervient.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-comment-utiliser-automapper-dans-notre-application\">Comment utiliser AutoMapper dans notre application<\/h2>\n\n\n\n<p>Voyons comment ajouter Automapper dans notre application .NET Core .<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-installation\">Installation d&rsquo;AutoMapper <\/h3>\n\n\n\n<p>La premi\u00e8re \u00e9tape consiste \u00e0 installer le package NuGet correspondant&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"asm\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection<\/pre>\n<\/div><\/div>\n\n\n\n<p>Si nous installons le <code>AutoMapper.Extensions.Microsoft.DependencyInjection<\/code> package , il installera automatiquement le package AutoMapper pour nous puisqu&rsquo;il y fait r\u00e9f\u00e9rence.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-configuration\">Configuration d&rsquo;AutoMapper <\/h3>\n\n\n\n<p>Nous expliquerons la configuration pour les versions .NET 5 et .NET 6 et sup\u00e9rieures.<\/p>\n\n\n\n<p>Apr\u00e8s avoir install\u00e9 le package requis, l&rsquo;\u00e9tape suivante consiste \u00e0 configurer les services. Faisons-le en <code>Startup.cs<\/code> classe :<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public void ConfigureServices(IServiceCollection services)\n{\n    services.AddAutoMapper(typeof(Startup));\n    services.AddControllersWithViews();\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p><strong>Pour .NET 6, nous devons modifier la classe Program :<\/strong><\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">builder.Services.AddAutoMapper(typeof(Program)); \nbuilder.Services.AddControllersWithViews();<\/pre>\n<\/div><\/div>\n\n\n\n<p>C&rsquo;est \u00e7a. AutoMapper est install\u00e9 et configur\u00e9 dans notre projet. Voyons maintenant comment l&rsquo;utiliser avec nos objets.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-usage\">Usage<\/h3>\n\n\n\n<p>Disons que nous avons un objet domaine nomm\u00e9 <code>User<\/code>:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class User\n{\n    public int Id { get; set; }\n    public string FirstName { get; set; }\n    public string LastName { get; set; }\n    public string Email { get; set; }\n    public string Address { get; set; }\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Dans la couche UI, nous aurions un <code>ViewModel<\/code> pour afficher les informations utilisateur&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class UserViewModel\n{\n    public string FirstName { get; set; }\n    public string LastName { get; set; }\n    public string Email { get; set; }\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Voyons maintenant comment nous allons convertir notre objet de domaine en un mod\u00e8le de vue.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-profils\">Profils<\/h3>\n\n\n\n<p>Une bonne fa\u00e7on d&rsquo;organiser nos configurations de mappage est avec <code>Profiles<\/code>. Nous devons cr\u00e9er des classes qui h\u00e9ritent de <code>Profile<\/code> class et mettre la configuration dans le constructeur&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public UserProfile()\n{\n    CreateMap&lt;User, UserViewModel>();\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p><code>UserProfile<\/code> La classe cr\u00e9e le mappage entre notre <code>User<\/code>objet de domaine et <code>UserViewModel<\/code>. D\u00e8s que notre application d\u00e9marre et initialise AutoMapper, AutoMapper analysera notre application et recherchera les classes qui h\u00e9ritent de la <code>Profile<\/code> classe et chargera leurs configurations de mappage.<\/p>\n\n\n\n<p>Maintenant, d\u00e9finissons un contr\u00f4leur et utilisons les fonctionnalit\u00e9s de mappage automatique que nous venons d&rsquo;ajouter&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class UserController : Controller\n{\n    private readonly IMapper _mapper;\n\n    public UserController(IMapper mapper)\n    {\n        _mapper = mapper;\n    }\n\n    public IActionResult Index()\n    {\n        \/\/ Populate the user details from DB\n        var user = GetUserDetails();\n\n        UserViewModel userViewModel = _mapper.Map&lt;UserViewModel>(user);\n\n        return View(userViewModel);\n    }\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Tout d&rsquo;abord, nous injectons l&rsquo; <code>mapper<\/code> objet dans le contr\u00f4leur. Ensuite, nous appelons la <code>Map()<\/code>m\u00e9thode, qui mappe l&rsquo; <code>User<\/code> objet \u00e0 l&rsquo; <code>UserViewModel<\/code> objet. De plus, faites attention \u00e0 une m\u00e9thode locale <code>GetUserDetails<\/code> que nous utilisons pour le stockage local des donn\u00e9es. Vous pouvez trouver son impl\u00e9mentation dans notre code source.<\/p>\n\n\n\n<p>Cr\u00e9ons une m\u00e9thode <code>View<\/code> pour l&rsquo; <code>Index<\/code> action comme expliqu\u00e9 dans la section de l&rsquo;article&nbsp;: Cr\u00e9ation de vues .<\/p>\n\n\n\n<p>Ex\u00e9cutons maintenant l&rsquo;application&nbsp;:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1010\" height=\"842\" src=\"https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image.png\" alt=\"AutoMapper dans ASP.NET Core\" class=\"wp-image-544\" srcset=\"https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image.png 1010w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-300x250.png 300w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-768x640.png 768w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-14x12.png 14w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-256x213.png 256w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-950x792.png 950w\" sizes=\"(max-width: 1010px) 100vw, 1010px\" \/><\/figure>\n\n\n\n<p>Nous pouvons voir que notre <code>User<\/code> objet de domaine est correctement mapp\u00e9 \u00e0 l&rsquo; <code>UserViewModel<\/code> objet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-mappage-vers-des-proprietes-avec-des-noms-differents\">Mappage vers des propri\u00e9t\u00e9s avec des noms diff\u00e9rents<\/h3>\n\n\n\n<p>Eh bien, c&rsquo;\u00e9tait assez simple, n&rsquo;est-ce pas ?&nbsp;<\/p>\n\n\n\n<p>Mais que se passe-t-il si nous avons des noms de propri\u00e9t\u00e9 diff\u00e9rents dans nos objets source et destination. Voyons comment faire le mappage dans ces cas.<\/p>\n\n\n\n<p>Modifions les noms de propri\u00e9t\u00e9 dans <code>UserViewModel<\/code> la classe&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class UserViewModel\n{\n    public string FName { get; set; }\n    public string LName { get; set; }\n    public string Email { get; set; }\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Ici, nous devons mapper les propri\u00e9t\u00e9s de l&rsquo; <code>User<\/code> objet domaine \u00e0 notre <code>UserViewModel<\/code>:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">User.FirstName -> UserViewModel.FName\nUser.LastName -> UserViewModel.LName\nUser.EMail -> UserViewModel.Email<\/pre>\n<\/div><\/div>\n\n\n\n<p>Modifions donc le mappage dans la <code>UserProfile<\/code> classe&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public UserProfile()\n{\n    CreateMap&lt;User, UserViewModel>()\n        .ForMember(dest =>\n            dest.FName,\n            opt => opt.MapFrom(src => src.FirstName))\n        .ForMember(dest =>\n            dest.LName,\n            opt => opt.MapFrom(src => src.LastName))\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Nous utilisons la <code>CreateMap()<\/code>m\u00e9thode pour cr\u00e9er un mappage en fournissant les propri\u00e9t\u00e9s source et destination.&nbsp;<\/p>\n\n\n\n<p>Si nous voulons personnaliser la configuration pour des membres individuels, nous pouvons utiliser la <code>ForMember()<\/code>m\u00e9thode qui a les param\u00e8tres <code>destinationMember<\/code><strong>, <\/strong>qui est de type <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.linq.expressions.expression?view=netcore-2.2\" target=\"_blank\" rel=\"noopener\">Expression<\/a> et <code>memberOptions<\/code><strong>, <\/strong>qui est de type <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.action-1?view=netcore-2.2\" target=\"_blank\" rel=\"noopener\">Action <\/a>.<\/p>\n\n\n\n<p>Par exemple, le code ci-dessus mappe <code>FirstName<\/code> et <code>LastName<\/code>les propri\u00e9t\u00e9s de l&rsquo; <code>User<\/code>objet \u00e0 la <code>FName<\/code> et \u00e0 la <code>LName<\/code> propri\u00e9t\u00e9 de <code>UserViewModel<\/code> respectivement.<\/p>\n\n\n\n<p>Apr\u00e8s avoir apport\u00e9 ces modifications, ex\u00e9cutons \u00e0 nouveau l&rsquo;application. Nous pouvons voir que ces propri\u00e9t\u00e9s sont correctement mapp\u00e9es.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-cartographie-inversee\">Cartographie invers\u00e9e<\/h3>\n\n\n\n<p>Jusqu&rsquo;\u00e0 pr\u00e9sent, nous n&rsquo;avons examin\u00e9 que le mappage unidirectionnel, ce qui signifie que si nous avons deux types <code>Type A<\/code> et <code>Type B<\/code>, nous mappons uniquement <code>Type A<\/code> vers <code>Type B<\/code>. Mais, en utilisant la capacit\u00e9 de mappage invers\u00e9 d&rsquo;Automapper, il est possible d&rsquo;obtenir un mappage bidirectionnel&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"true\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public UserProfile()\n{\n    CreateMap&lt;User, UserViewModel>()\n        .ForMember(dest =>\n            dest.FName,\n            opt => opt.MapFrom(src => src.FirstName))\n        .ForMember(dest =>\n            dest.LName,\n            opt => opt.MapFrom(src => src.LastName))\n        .ReverseMap();\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Une fois le Reverse Mapping configur\u00e9, nous pouvons remonter de la destination au type de source&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var mappedUser = _mapper.Map&lt;User>(userViewModel);<\/pre>\n<\/div><\/div>\n\n\n\n<p>De cette fa\u00e7on, nous pouvons facilement r\u00e9aliser un mappage bidirectionnel entre les types \u00e0 l&rsquo;aide des capacit\u00e9s de mappage invers\u00e9 d&rsquo;AutoMapper.&nbsp;<\/p>\n\n\n\n<p>Juste une note. Nous pouvons \u00e9galement utiliser AutoMapper de la m\u00eame mani\u00e8re dans <a href=\"https:\/\/code--maze-com.translate.goog\/ultimate-aspnet-core-3-web-api\/?_x_tr_sl=en&amp;_x_tr_tl=fr&amp;_x_tr_hl=fr&amp;_x_tr_pto=wapp\" target=\"_blank\" rel=\"noreferrer noopener\">le projet d&rsquo;API Web ASP.NET Core<\/a> , l&rsquo;impl\u00e9mentation est la m\u00eame, nous ne mapperons pas les mod\u00e8les de vue mais, par exemple, nos classes DTO.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-dans-les-coulisses\">Dans les coulisses d&rsquo;AutoMapper <\/h2>\n\n\n\n<p>Nous avons vu la magie d&rsquo;AutoMapper en action. Alors que se passe-t-il en arri\u00e8re-plan ?&nbsp;<\/p>\n\n\n\n<p>AutoMapper utilise un concept de programmation appel\u00e9 <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/reflection\" target=\"_blank\" rel=\"noopener\">Reflection <\/a>pour r\u00e9cup\u00e9rer les m\u00e9tadonn\u00e9es de type des objets. Nous pouvons utiliser la r\u00e9flexion pour obtenir dynamiquement le type d&rsquo;un objet existant et invoquer ses m\u00e9thodes ou acc\u00e9der \u00e0 ses champs et propri\u00e9t\u00e9s.&nbsp;<\/p>\n\n\n\n<p>Ensuite, en fonction des conventions et des configurations d\u00e9finies, nous pouvons facilement mapper les propri\u00e9t\u00e9s des deux types. AutoMapper a \u00e9t\u00e9 construit autour de ce concept.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-consignes-dutilisation-et-bonnes-pratiques\">Consignes d&rsquo;utilisation et bonnes pratiques d&rsquo;AutoMapper <\/h2>\n\n\n\n<p>Comme pour tous les autres composants que nous utilisons dans notre application, il existe certaines directives d&rsquo;utilisation et les meilleures pratiques que nous devons suivre lors de l&rsquo;utilisation d&rsquo;AutoMapper.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-a-faire\"><strong>\u00c0 faire&nbsp;<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Utilisez toujours le <code>AutoMapper.Extensions.Microsoft.DependencyInjection<\/code> package dans ASP.NET Core avec <code>services.AddAutoMapper(assembly[])<\/code>. Ce package effectuera toute l&rsquo;analyse et l&rsquo; enregistrement de l&rsquo;injection de  d\u00e9pendances . Nous avons seulement besoin de d\u00e9clarer les configurations de profil.<\/li>\n\n\n\n<li>Organisez toujours la configuration en <code>Profiles<\/code>. <code>Profiles<\/code> permettent de regrouper une configuration commune et d&rsquo;organiser les mappings par usage. Cela nous permet de rapprocher la configuration de mappage de l&rsquo;endroit o\u00f9 elle est utilis\u00e9e, au lieu d&rsquo;un seul fichier de configuration qui devient difficile \u00e0 modifier\/maintenir.<\/li>\n\n\n\n<li>Utilisez toujours les options de configuration prises en charge par LINQ plut\u00f4t que leurs homologues, car les extensions de requ\u00eate LINQ offrent les meilleures performances de toutes les strat\u00e9gies de mappage.<\/li>\n\n\n\n<li>Toujours aplatir les DTO. AutoMapper peut g\u00e9rer les propri\u00e9t\u00e9s de mappage ABC dans ABC. En aplatissant notre mod\u00e8le, nous cr\u00e9ons un objet plus simplifi\u00e9 qui ne n\u00e9cessitera pas beaucoup de navigation pour acc\u00e9der aux donn\u00e9es.<\/li>\n\n\n\n<li>Mettez toujours des propri\u00e9t\u00e9s calcul\u00e9es simples communes dans le mod\u00e8le source. De m\u00eame, nous devons placer les propri\u00e9t\u00e9s calcul\u00e9es sp\u00e9cifiques au mod\u00e8le de destination dans le mod\u00e8le de destination.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"aioseo-a-ne-pas-faire\"><strong>A ne pas faire<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>N&rsquo;appelez pas <code>CreateMap()<\/code>\u00e0 chaque demande. Il n&rsquo;est pas recommand\u00e9 de cr\u00e9er la configuration pour chaque demande de mappage. La configuration du mappage doit \u00eatre effectu\u00e9e une fois au d\u00e9marrage.<\/li>\n\n\n\n<li>N&rsquo;utilisez pas de cartes en ligne. Les cartes en ligne peuvent sembler plus faciles pour des sc\u00e9narios tr\u00e8s simples, mais nous perdons la facilit\u00e9 de configuration.<\/li>\n\n\n\n<li>Si nous devons \u00e9crire un comportement de mappage complexe, il serait peut-\u00eatre pr\u00e9f\u00e9rable d&rsquo;\u00e9viter d&rsquo;utiliser <code>AutoMapper<\/code> pour ce sc\u00e9nario.<\/li>\n\n\n\n<li>Ne placez aucune logique qui ne corresponde pas strictement au comportement de mappage dans la configuration. <code>AutoMapper<\/code> ne doit pas ex\u00e9cuter de logique m\u00e9tier, il ne doit g\u00e9rer que le mappage.<\/li>\n\n\n\n<li>\u00c9vitez de partager des DTO sur plusieurs cartes. Mod\u00e9lisez vos DTO autour d&rsquo;actions individuelles, et si vous devez le modifier, vous n&rsquo;affectez que cette action.<\/li>\n\n\n\n<li>Ne cr\u00e9ez pas de DTO avec des associations circulaires. <code>AutoMapper<\/code> le prend en charge, mais cela pr\u00eate \u00e0 confusion et peut entra\u00eener de tr\u00e8s mauvaises performances. Au lieu de cela, nous pouvons cr\u00e9er des DTO distincts pour chaque niveau de la hi\u00e9rarchie que nous voulons.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-aplatir-des-modeles-dobjets-complexes\">Aplatir des mod\u00e8les d&rsquo;objets complexes dans AutoMapper <\/h2>\n\n\n\n<p><code>AutoMapper<\/code> prend en charge l&rsquo;aplatissement des mod\u00e8les d&rsquo;objets complexes en DTO ou un autre mod\u00e8le d&rsquo;objet simple. Par exemple, les objets de domaine &nbsp;ont g\u00e9n\u00e9ralement un mod\u00e8le d&rsquo;objet complexe avec de nombreuses associations entre eux, mais les ViewModels ont g\u00e9n\u00e9ralement un mod\u00e8le d&rsquo;objet plat.&nbsp;<\/p>\n\n\n\n<p>Nous pouvons mapper des objets de domaine sur des ViewModels avec Flattening d&rsquo; <a href=\"https:\/\/docs.automapper.org\/en\/stable\/Flattening.html\" target=\"_blank\" rel=\"noopener\">AutoMapper <\/a>.&nbsp;<\/p>\n\n\n\n<p>Si nous suivons les conventions de d\u00e9nomination appropri\u00e9es pour nos mod\u00e8les d&rsquo;objets, il n&rsquo;est pas n\u00e9cessaire de fournir de code de configuration suppl\u00e9mentaire. <code>AutoMapper<\/code> fonctionne avec des conventions et mappe notre mod\u00e8le d&rsquo;objet du complexe au plat\/simple.<\/p>\n\n\n\n<p><code>AutoMapper<\/code> utilise les conventions suivantes :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Il mappera automatiquement les propri\u00e9t\u00e9s avec les m\u00eames noms.<\/li>\n\n\n\n<li>Si l&rsquo;objet source est associ\u00e9 \u00e0 d&rsquo;autres objets, il essaiera de mapper avec des propri\u00e9t\u00e9s sur l&rsquo;objet de destination dont le nom est une combinaison du nom de la classe source et du nom de la propri\u00e9t\u00e9 dans le <a href=\"https:\/\/en.wikipedia.org\/wiki\/Camel_case\">cas Pascal <\/a>.&nbsp;<\/li>\n\n\n\n<li>Il essaiera de mapper des m\u00e9thodes sur l&rsquo;objet source qui a un <code>Get<\/code> pr\u00e9fixe avec une propri\u00e9t\u00e9 sur l&rsquo;objet de destination avec le nom excluant le <code>Get<\/code> pr\u00e9fixe.<\/li>\n<\/ul>\n\n\n\n<p>Si nous suivons ces conventions, <code>AutoMapper<\/code> mappera automatiquement nos objets. Sinon, nous devrons configurer \u00e0 l&rsquo; <code>AutoMapper<\/code> aide de l&rsquo; <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fluent_interface\" target=\"_blank\" rel=\"noopener\">API Fluent <\/a>.<\/p>\n\n\n\n<p>Modifions notre <code>User<\/code>objet en ajoutant un objet enfant <code>Address<\/code>:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class User\n{\n    public int Id { get; set; }\n    public string FirstName { get; set; }\n    public string LastName { get; set; }\n    public string Email { get; set; }\n    public Address Address { get; set; }\n\n    public string GetFullName()\n    {\n        return $\"{this.LastName}, {this.FirstName}\";\n    }\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Et voici \u00e0 quoi <code>Address<\/code> ressemble la classe :<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class Address\n{\n    public int Id { get; set; }\n    public string Door { get; set; }\n    public string Street1 { get; set; }\n    public string Street2 { get; set; }\n    public string City { get; set; }\n    public string State { get; set; }\n    public string Country { get; set; }\n    public string ZipCode { get; set; }\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Notez \u00e9galement que nous avons ajout\u00e9 une m\u00e9thode <code>GetFullName()<\/code>pour obtenir le nom complet de l&rsquo;utilisateur.<\/p>\n\n\n\n<p>Modifions la <code>UserViewModel<\/code> classe&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class UserViewModel\n{\n    [Display(Name = \"Full Name\")]\n    public string FullName { get; set; }\n    [Display(Name = \"Country\")]\n    public string AddressCountry { get; set; }\n    public string Email { get; set; }\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Maintenant, modifions la classe de profil pour utiliser les conventions par d\u00e9faut&nbsp;:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public UserProfile()\n{\n    CreateMap&lt;User, UserViewModel>();\n}<\/pre>\n<\/div><\/div>\n\n\n\n<p>Ex\u00e9cutons \u00e0 nouveau l&rsquo;application&nbsp;:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"903\" height=\"840\" src=\"https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-1.png\" alt=\"AutoMapper dans ASP.NET Core\" class=\"wp-image-564\" srcset=\"https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-1.png 903w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-1-300x279.png 300w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-1-768x714.png 768w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-1-13x12.png 13w, https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/image-1-256x238.png 256w\" sizes=\"(max-width: 903px) 100vw, 903px\" \/><\/figure>\n\n\n\n<p>Cette fois, nous pouvons voir que la <code>GetFullName()<\/code>m\u00e9thode sur l&rsquo;objet source est correctement mapp\u00e9e \u00e0 la <code>FullName<\/code> propri\u00e9t\u00e9 sur l&rsquo;objet de destination.<\/p>\n\n\n\n<p>De m\u00eame, la propri\u00e9t\u00e9 User.Address.Country est automatiquement mapp\u00e9e sur <code>UserViewModel.AddressCountry<\/code>.&nbsp;<\/p>\n\n\n\n<p>Ces mappages sont correctement g\u00e9r\u00e9s par l&rsquo; \u00e0 l&rsquo; <code>AutoMapper<\/code> aide de ses conventions par d\u00e9faut.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-conclusion\">Conclusion<\/h2>\n\n\n\n<p>Dans cet article, nous avons appris les concepts suivants :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le composant AutoMapper \u2013 qu&rsquo;est-ce que c&rsquo;est et quand l&rsquo;utiliser ?<\/li>\n\n\n\n<li>Installation, configuration et utilisation du composant AutoMapper dans notre application ASP.NET Core<\/li>\n\n\n\n<li>Comment AutoMapper fonctionne dans les coulisses<\/li>\n\n\n\n<li>Consignes d&rsquo;utilisation et meilleures pratiques lors de l&rsquo;utilisation d&rsquo;AutoMapper.<\/li>\n\n\n\n<li>Aplatir un mod\u00e8le d&rsquo;objet complexe \u00e0 l&rsquo;aide des conventions par d\u00e9faut d&rsquo;AutoMapper.<\/li>\n<\/ul>\n\n\n\n<p>C&rsquo;est tout pour le moment. J&rsquo;esp\u00e8re que vous avez appr\u00e9ci\u00e9 l&rsquo;article. Nous aborderons des sujets plus avanc\u00e9s li\u00e9s \u00e0 AutoMapper dans l&rsquo;un des articles suivants .<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"aioseo-derniers-articles\">Derniers Articles<\/h2>\n\n\n\n<ul class=\"wp-block-list\" id=\"block-957e2f94-bcbc-4609-b8f3-4ca3d686660e\">\n<li><a href=\"https:\/\/oussamasaidi.com\/en\/hangfire-avec-asp-net-core\/\">Hangfire avec ASP.NET Core<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/oussamasaidi.com\/en\/automapper-net-core\/\">Premiers pas avec AutoMapper dans ASP.NET Core<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/oussamasaidi.com\/en\/serilog-in-aspnet-core-3-1\/\">Serilog dans ASP.NET Core 3.1-La journalisation structur\u00e9e simplifi\u00e9e<\/a><\/li>\n<\/ul>\n\n\n\n<div class=\"wp-container-6 wp-block-columns alignwide\">\n<div class=\"wp-container-5 wp-elements-e1ba0e3d9d30b7fec5c25e47c471e6ef wp-block-column has-text-color has-background has-link-color\" style=\"background-color:#c0ebf1;color:#000000;padding-top:2em;padding-right:2em;padding-bottom:2em;padding-left:2em\">\n<h2 id=\"patron\" style=\"font-size:40px\"><strong>Vous aimez le contenu&nbsp;?<\/strong><\/h2>\n\n\n\n<p class=\"has-normal-font-size\"><strong>Si vous aimez mes articles, pensez \u00e0 m\u2019acheter quelques caf\u00e9s !<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-wide\">\n\n\n\n<div class=\"wp-container-4 is-horizontal is-content-justification-center wp-block-buttons alignfull\">\n<div class=\"wp-block-button has-custom-width wp-block-button__width-100\"><a class=\"wp-block-button__link has-white-color has-text-color has-background no-border-radius\" href=\"https:\/\/www.buymeacoffee.com\/oussamasaiI\" style=\"background-color:#000000\" target=\"_blank\" rel=\"noreferrer noopener\">Achetez-moi un caf\u00e9<\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Dans cet article, nous allons apprendre \u00e0 utiliser AutoMapper dans une application ASP.NET Core . Nous allons commencer par examiner&#8230; <\/p>\n<div class=\"art-el-more\"><a href=\"https:\/\/oussamasaidi.com\/en\/automapper-net-core\/\" class=\"art-link art-color-link art-w-chevron\">Read more<\/a><\/div>","protected":false},"author":1,"featured_media":522,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[40,45,55,41,56],"tags":[47,48,57,49,54,53],"ppma_author":[286],"class_list":["post-520","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-netcore","category-asp-net","category-automapper","category-c","category-c-2","tag-net-core","tag-asp-net","tag-automapper","tag-c-sharp","tag-c","tag-dot-net-core"],"acf":[],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/09\/net-core-automapper.webp","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":660,"url":"https:\/\/oussamasaidi.com\/en\/best-libraries-for-aspnet-core\/","url_meta":{"origin":520,"position":0},"title":"15 meilleures biblioth\u00e8ques pour les d\u00e9veloppeurs ASP.NET Core","author":"Saidi Oussama","date":"November 23, 2022","format":false,"excerpt":"Plusieurs nouveaux d\u00e9veloppeurs font quotidiennement leurs premiers pas dans ASP.Net Core pour leur carri\u00e8re de d\u00e9veloppement Web. Choisir et ma\u00eetriser les meilleures biblioth\u00e8ques qui aident \u00e0 optimiser l'exp\u00e9rience de d\u00e9veloppement est le facteur d\u00e9cisif pour toute technologie. Avec la croissance rapide de .NET Core au cours des derni\u00e8res ann\u00e9es, plusieurs\u2026","rel":"","context":"In &quot;.Net Core&quot;","block_context":{"text":".Net Core","link":"https:\/\/oussamasaidi.com\/en\/category\/netcore\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/02\/pngaaa.com-592393.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/02\/pngaaa.com-592393.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/02\/pngaaa.com-592393.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/02\/pngaaa.com-592393.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/02\/pngaaa.com-592393.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/02\/pngaaa.com-592393.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":399,"url":"https:\/\/oussamasaidi.com\/en\/serilog-in-aspnet-core-3-1\/","url_meta":{"origin":520,"position":1},"title":"Ma\u00eetriser les Logs Structur\u00e9s avec Serilog dans ASP.NET Core 8","author":"Saidi Oussama","date":"September 21, 2022","format":false,"excerpt":"Guide Complet Serilog avec Exemples pour SQL Server et le Cloud Introduction Aujourd'hui, les applications modernes g\u00e9n\u00e8rent des volumes croissants de donn\u00e9es. Pour les d\u00e9velopper efficacement, une solution de journalisation robuste devient indispensable. Parmi les outils disponibles, Serilog se distingue comme l'une des meilleures biblioth\u00e8ques de logging pour .NET. Dans\u2026","rel":"","context":"In &quot;.Net Core&quot;","block_context":{"text":".Net Core","link":"https:\/\/oussamasaidi.com\/en\/category\/netcore\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/07\/serilog-dotnet-core.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/07\/serilog-dotnet-core.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/07\/serilog-dotnet-core.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/07\/serilog-dotnet-core.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2022\/07\/serilog-dotnet-core.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":838,"url":"https:\/\/oussamasaidi.com\/en\/comment-implementer-authentification-cle-api-aspnet-core\/","url_meta":{"origin":520,"position":2},"title":".NET Core : impl\u00e9menter l\u2019authentification par cl\u00e9 API en C#","author":"Saidi Oussama","date":"August 22, 2024","format":false,"excerpt":"ContexteCr\u00e9ation de l'attribut de cl\u00e9 APIImpl\u00e9menter du filtre d'autorisation ApiKeyimpl\u00e9mentation de l'ApiKeyValidatorTester l'APIUtilisez le middlewareConclusionDerniers Articles Vous pouvez trouver le code source complet sur github Contexte Alors, qu\u2019est-ce que l\u2019authentification par cl\u00e9 API dans ASP.NET Core ? Prenons un exemple concret. Imaginez que vous ayez d\u00e9velopp\u00e9 un tableau de bord\u2026","rel":"","context":"In &quot;.Net Core&quot;","block_context":{"text":".Net Core","link":"https:\/\/oussamasaidi.com\/en\/category\/netcore\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2024\/07\/Capture00.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2024\/07\/Capture00.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2024\/07\/Capture00.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1086,"url":"https:\/\/oussamasaidi.com\/en\/logging-centralise-avec-opentelemetry-dans-net-core\/","url_meta":{"origin":520,"position":3},"title":"Logging Centralis\u00e9 avec OpenTelemetry dans .NET Core","author":"Saidi Oussama","date":"April 7, 2025","format":false,"excerpt":"Diagramme officiel OpenTelemetry montrant le flux de donn\u00e9es. Source originale. Introduction Dans le monde du d\u00e9veloppement moderne, la gestion des logs est devenue un \u00e9l\u00e9ment critique pour assurer la stabilit\u00e9 et la performance des applications. OpenTelemetry \u00e9merge comme la solution ultime pour impl\u00e9menter une strat\u00e9gie de logging centralis\u00e9e efficace. Ce\u2026","rel":"","context":"In &quot;.Net Core&quot;","block_context":{"text":".Net Core","link":"https:\/\/oussamasaidi.com\/en\/category\/netcore\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/ChatGPT-Image-8-avr.-2025-00_36_08.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/ChatGPT-Image-8-avr.-2025-00_36_08.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/ChatGPT-Image-8-avr.-2025-00_36_08.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/ChatGPT-Image-8-avr.-2025-00_36_08.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/ChatGPT-Image-8-avr.-2025-00_36_08.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/ChatGPT-Image-8-avr.-2025-00_36_08.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":1035,"url":"https:\/\/oussamasaidi.com\/en\/creer-un-chatbot-avec-deepseek-et-net-9-tutoriel-complet\/","url_meta":{"origin":520,"position":4},"title":"Cr\u00e9er un Chatbot avec DeepSeek et .NET 9 : Tutoriel Complet","author":"Saidi Oussama","date":"April 6, 2025","format":false,"excerpt":"Ce tutoriel vous guidera pas \u00e0 pas pour construire un chatbot utilisant l'API de DeepSeek avec .NET 9. Nous allons cr\u00e9er une application web de chatbot avec ASP.NET Core. Pr\u00e9requis\u00c9tape 1 : Cr\u00e9er une nouvelle application Web ASP.NET Core\u00c9tape 2 : Ajouter les packages n\u00e9cessaires\u00c9tape 3 : Cr\u00e9er les mod\u00e8les\u2026","rel":"","context":"In &quot;.Net Core&quot;","block_context":{"text":".Net Core","link":"https:\/\/oussamasaidi.com\/en\/category\/netcore\/"},"img":{"alt_text":"AI Chatbot with .net core","src":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/https___dev-to-uploads.s3.amazonaws.com_uploads_articles_w4yx4rdp1ohuvcb96ypg.webp?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/https___dev-to-uploads.s3.amazonaws.com_uploads_articles_w4yx4rdp1ohuvcb96ypg.webp?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/https___dev-to-uploads.s3.amazonaws.com_uploads_articles_w4yx4rdp1ohuvcb96ypg.webp?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/04\/https___dev-to-uploads.s3.amazonaws.com_uploads_articles_w4yx4rdp1ohuvcb96ypg.webp?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1714,"url":"https:\/\/oussamasaidi.com\/en\/https-oussamasaidi-com-restful-api-mastery-best-practices-with-asp-net-core-part-2\/","url_meta":{"origin":520,"position":5},"title":"RESTful API best practices\u00a0with ASP.NET Core Part 2","author":"Saidi Oussama","date":"December 20, 2025","format":false,"excerpt":"Testing, Performance, Security, Microservices & Deployment Introduction: From Solid Foundations to Production Excellence In Part 1 of RESTful API Mastery, we established the architectural and technical foundations required to build reliable, evolvable RESTful APIs with ASP.NET Core. However, a well-designed API only becomes truly valuable when it is tested, observable,\u2026","rel":"","context":"In &quot;.Net Core&quot;","block_context":{"text":".Net Core","link":"https:\/\/oussamasaidi.com\/en\/category\/netcore\/"},"img":{"alt_text":"RESTful API Mastery","src":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/12\/restful-api-mastery-best-practices-with-asp-net-core-2r.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/12\/restful-api-mastery-best-practices-with-asp-net-core-2r.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/12\/restful-api-mastery-best-practices-with-asp-net-core-2r.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/12\/restful-api-mastery-best-practices-with-asp-net-core-2r.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/12\/restful-api-mastery-best-practices-with-asp-net-core-2r.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/oussamasaidi.com\/wp-content\/uploads\/2025\/12\/restful-api-mastery-best-practices-with-asp-net-core-2r.png?resize=1400%2C800&ssl=1 4x"},"classes":[]}],"authors":[{"term_id":286,"user_id":1,"is_guest":0,"slug":"oussama_sa","display_name":"Saidi Oussama","avatar_url":{"url":"https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/02\/001_001_cv1.jpg","url2x":"https:\/\/oussamasaidi.com\/wp-content\/uploads\/2022\/02\/001_001_cv1.jpg"},"author_category":"1","first_name":"Oussama","last_name":"SAIDI","user_url":"https:\/\/oussamasaidi.com","job_title":"Senior Fullstack .NET Developer","description":"I\u2019m a Senior Fullstack .NET Developer specializing in building scalable, high-performance web applications with .NET, C#, and modern frontend frameworks like React.js. I\u2019m passionate about clean architecture, automated testing, and sharing knowledge through blogs and tutorials."}],"_links":{"self":[{"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/posts\/520","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/comments?post=520"}],"version-history":[{"count":1,"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/posts\/520\/revisions"}],"predecessor-version":[{"id":1743,"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/posts\/520\/revisions\/1743"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/media\/522"}],"wp:attachment":[{"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/media?parent=520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/categories?post=520"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/tags?post=520"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/oussamasaidi.com\/en\/wp-json\/wp\/v2\/ppma_author?post=520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}