EntityFramework Core (EF Core) dans .NET - La meilleure documentation !

Tout le monde y va de son petit sample, de son exemple d'utilisation d'Entity Framework Core. Moi même j'ai pu décrire de temps en temps quelques commandes EF Core et puis je trouve la page ultime, celle qui remplace toutes les autres pages le site de la meilleure documentation sur Entity Framework Core.

La documentation qui est à la fois un tutorial intéressant à suivre même pour les plus expérimentés. Une documentation qui décrit l'intégralité de toutes les fonctions avec des exemples simples et bien construits à croire que cela ne peut pas être quelqu'un de Redmond car ils ne nous ont pas habitué à une telle documentation sur un produit.

Je pense que c'est l'effet OpenSource et ma fois, je suis bien content d'avoir trouvé ce site auquel je me réfère chaque fois que j'ai besoin d'approfondir mes connaissances de l'Entity Framework Core :

https://www.entityframeworktutorial.net/efcore/entity-framework-core.aspx
La meilleure documentation sur Entity Framework Core the Ultimate Documentation

C'est un exemple de documentation à suivre, il est fabuleux !

Have fun!

Authentification des Applications ASP.NET Core avec IdentityServer4 et Identity

Après un article complet sur le sujet de l'authentification des applications web. Je souhaite élargir mes connaissances à la découverte et à l'utilisation d'IdentityServer4.

Petite note personnelle, je suis très surpris de trouver ça :

\AngularAspNetCoreAuthen\Areas\Identity\Pages\Account\Register.cshtml.cs
namespace AngularAspNetAuthen.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class RegisterModel : PageModel
    {
        private readonly SignInManager<ApplicationUser> _signInManager;

\AspNetCoreMvcAuthen\Areas\Identity\Pages\Account\Register.cshtml.cs
namespace AspNetCoreMvcAuthen.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class RegisterModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;


C'est curieux on dirait que le model d'application ASP.NET Core Angular est plus évolué que celui d'MVC ... à méditer.

Bon maintenant que je sais faire du Scaffolding sur L'Identity voici après étude des différentes solutions le modèle de base que je vais utiliser :

https://github.com/damienbod/IdentityServer4AspNetCoreIdentityTemplate


https://github.com/damienbod/IdentityServer4AspNetCoreIdentityTemplate
IdentityServer4AspNetCoreIdentityTemplate

An ASP.NET Core IdentityServer4 Identity Template with Bootstrap 4 and Localization

CQFD

Comment faire des Logs dans ASP.NET Core C#

Cela fait cent fois que l'on parle de log nous avons résolut le problème avec Log4Net pendant deux bonnes décennies mais c'est comme tout, les choses changent. Alors aujourd'hui ce qui est le mieux intégré à ASP.NET Core c'est Serilog.

Qu'à cela ne tienne, allons y rapidement, pour faire des Logs dans mon Projet ASP.NET Core avec Serilog le plus simplement du monde.

Il faut installer les packages suivants :
NuGet Packages  pour Serilog
C'est bon de la noter car maintenant chaque fois que j'instancie un nouveau projet, je me vois obligé de copier ces quelques lignes dans mon nouveau projet tellement c'est simple et efficace.

Dans mon fichier Startup.cs
J'écris le code de la fonction suivante :

private void ConfigureLoggerFactory( ILoggerFactory loggerFactory )
{
    string date = DateTime.Now.ToString();
    date = date.Replace( "/", "" );
    date = date.Replace( " ", "_" );
    date = date.Replace( ":", "-" );
    string logfileName = $"Log/log_{date}.txt";

    var serilog = new LoggerConfiguration()
        .MinimumLevel.Verbose()
        .Enrich.FromLogContext()
        .WriteTo.File( logfileName );


    loggerFactory.WithFilter( new FilterLoggerSettings
     {
         { "IdentityServer4", LogLevel.Debug },
         { "Microsoft", LogLevel.Warning },
         { "System", LogLevel.Warning },
     } ).AddSerilog( serilog.CreateLogger() );
}


Que j'appelle dans la fonction Configure de la façon suivante :

public void Configure( IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory )

ConfigureLoggerFactory( loggerFactory );

Voilà, l'intérêt de faire ainsi c'est que l'on récupère des logs en provenance des modules System, Microsoft, et IdentityServer4.

N'oubliez pas de consulter :

C#.NET - Serilog Log Not Working

Pour savoir comment configurer les Logs

CQFD

Comment ajouter des données personnelles aux Base d'authentification ASP.NET Core ?

De base il y a le nom, l'adresse email, la structure d'une application ASP.NET Core concernant l'authentification est déjà assez complète mais je souhaite y ajouter des données personnelles sur l'utilisateur âge ou date de naissance, adresse, localisation qu'il va pouvoir gérer dans son profile au sein de mon Application Web ASP.NET Core.



https://identityserver.io/
Authentification dans les application ASP.NET Core & Angular
Je crois que quasiment tout le travaille est déjà fait ...

Microsoft - Ajouter, télécharger et supprimer des données utilisateur personnalisées pour l’identité dans un projet ASP.NET Core

En continuant mes recherches, je trouve ce projet et cet auteur qui me semble bien avancé :

Mark Macneil - User Authentication and Identity with Angular, Asp.Net Core and IdentityServer
Ce qui est un petit peu ennuyeux pour ne pas dire plus, c'est la disparité de tous ces projets. Je clone

https://github.com/mmacneil/AngularASPNETCoreOAuth

et je m'intéresse précisément au projet suivant :

https://github.com/mmacneil/AngularASPNETCoreOAuth/tree/master/src/AuthServer

Car je souhaite également déployer une application d'Authentification pour authentifier des utilisateurs dans mes applications Angular.

Je lance la solution dans mon Visual Studio, jusque là tout vas bien, mais quand je souhaite créer la base de données, je vais dans la console Package Management Console :

PM> update-database

Et là ce sont des insultes jusqu' à ce que je comprenne que le package :

Microsoft.EntityFrameworkCore.Tools

N'est pas installé et pourtant cette commande en dépend, allons y installons ce package pour ce projet:

PM> Install-Package Microsoft.EntityFrameworkCore.Tools

Mais là pareil, un flot d'injures le tout en rouge dans ma PMC, jusqu'à ce que je mette à jour la version des packages ...


Mise à jour des packages autour d'EntityFrameworkCore  pour installer EntityFrameworkCore.Tools
Mise à jour des packages autour d'EntityFrameworkCore  pour installer EntityFrameworkCore.Tools
Cette fois, je vais enfin pouvoir exécuter la fameuse commande :

PM> update-database

Et bien non rien à faire ...


Update-database
Your startup project 'AuthServer' doesn't reference Microsoft.EntityFrameworkCore.Design. This package is required for the Entity Framework Core Tools to work. Ensure your startup project is correct, install the package, and try again.

Cette fois j'en ai ras le bol, je pars, je reviendrai demain ...

Le lendemain ... Reprenons calmement ...

J'installe le package Microsoft.EntityFrameworkCore.Design pour le projet principal AuthServer


Install package Microsoft.EntityFrameworkCore.Design
Je me positionne dans le répertoire de l'Infra :

PM> cd .\AuthServer.Infrastructure
PM> update-database
Build started...
Build succeeded.
More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands.
PM>

Là, on retourne chez l'auteur qui nous dit :

AuthServer.Infrastructure> dotnet ef database update --context AppIdentityDbContext
AuthServer.Infrastructure> dotnet ef database update --context PersistedGrantDbContext

et que l'on va traduire par la commande suivante dans la Console Package Management :

PM> update-database -context AppIdentityDbContext
Build started...
Build succeeded.
DesignTimeDbContextFactory.Create(string): Connection string: Server=(localdb)\mssqllocaldb;Database=AuthServer;Trusted_Connection=True;MultipleActiveResultSets=true
Applying migration '20190403041320_initial'.
Done.
PM>

La documentation est Ici :

Microsoft EF Core - Migrations

Aaaahhhh c'est la lutte quand même, encore un machin très microsoftien c'est la multiplication des fenêtres d'exécution (des consoles) entre PowerShell Package Management Console ou même Windows Console avec dotnet ...

Ma Base de donnée d'Authentification des Utilisateurs est enfin crée :


ASP.NET Core DB - Base d'Authentification des utilisateurs
Il ne faut pas oublier d'exécuter la deuxième commande :

PM> update-database -context PersistedGrantDbContext

Et pour le message :

Method not found: 'Microsoft.EntityFrameworkCore.Metadata.Builders.IndexBuilder Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder`1.HasIndex(System.Linq.Expressions.Expression`1<System.Func`2<!0,System.Object>>)'.

La solution préconisée est  Ici.

C'est de bien mettre à jour tous vos projets en vous assurant qu'ils utilisent la même version de IdentityServer ... Sinon, Beug !

PM> update-database -context PersistedGrantDbContext
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.1.2 initialized 'PersistedGrantDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (26ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (22ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [MigrationId], [ProductVersion]
      FROM [__EFMigrationsHistory]
      ORDER BY [MigrationId];
Microsoft.EntityFrameworkCore.Migrations[20405]
      No migrations were applied. The database is already up to date.
No migrations were applied. The database is already up to date.
Done.

PM>

Voilà pour la partie, Serveur d'Authentification.

Authentification - Partie cliente avec Angular

Cette fois, je prends mon Visual Studio Code et je viens ouvrir le répertoire :

\Visual Studio 2019\Samples\AngularASPNETCoreOAuth\src\Spa\oauth-client

Et je viens exécuter la commande dans un Terminal :


Client Angular - Visual Studio Core pour l'install de Angular/CLI
Je dois installer Angular CLI pour mon application cliente :

PS : \AngularASPNETCoreOAuth\src\Spa\oauth-client> ng install @angular/cli

Pour rappel l'installation d'Angular CLI se distingue par l'existence du répertoire :

\AngularASPNETCoreOAuth\src\Spa\oauth-client\node_modules\@angular

Une fois Angular/CLI installé, je peux lancer la compilation de mon application Angular :

PS : \AngularASPNETCoreOAuth\src\Spa\oauth-client> ng serve

Exécution en mode Debug de la partie Angular

Il me faut créer un fichier de configuration de l'exécution du mode Debug :



Angular Run en mode Debug
Angular Run en mode Debug

N'oubliez pas de modifier le port de communication proposé par défaut pour une application web : 8080 par le port 4200 pour les applications Web Angular.


Angular Run en mode Debug
Vous pouvez enfin cliquer sur le petit triangle vert et obtenir le résultat suivant en exécutant la partie cliente SPA (Single Page Application) :


Angular Authentification sur un Serveur ASP.NET Core avec IdentityServer
Angular Authentification sur un Serveur ASP.NET Core avec IdentityServer

Je me "Signup" avec un UserName : "aaa", je me Login et j'obtiens l'accès  à la "Top Secret Area" :


Angular Authentification sur un Serveur ASP.NET Core avec IdentityServer - Top Secret Area
Voilà, il est vraiment super cet exemple et très complet et mériterait un bisou sauf que nous sommes en période de Corona.

Thank you very much Mark Macneil

Mais vous l'avez vu pour aller au bout de cette application ,il y a plein de pièges que j'ai déjoués pour nous alors n'hésitez pas à cliquer partout, à commenter, à compléter.

La prochaine fois nous verrons comment ajouter des données autour de "MemberIdentity" car moi j'aimerais bien savoir où il habite mon utilisateur ;-)

Let's go to the beach!

Ah non, mince, c'est Corona, Grrrrr.

Je vous propose de poursuivre cette exploration des Bases de Données d'Authentification dans ASP.NET C# car cela concerne plus les applications Web.

ASP.NET Core comparaison des structures des Bases de données IdentityServer



StackOverflow - SeriLog LogDebug not working

Je lis ce message sur le site Stack Overflow : J'ai une application Web ASP.Net5 avec serilog configuré. Dans mon contrôleur personnel, j'imprime un message d'avertissement, d'erreur, de détail et de débogage, mais sur ma console, seuls les messages d'avertissement, d'erreur et de détail s'affichent.

Alors, comme je ne peux pas répondre là bas, je vais répondre ici ... car le réponse qui est donnée sur le site de StackOverFlow n'est pas la bonne !

ASPNet5 SeriLog LogDebug not working

I have the same issue, Debug Level is after the Verbose Level so it should work.
If Instead of using your own Logger, you direct use the Serilog one :
Serilog.Log.Verbose( "1. Log Verbose" );
Serilog.Log.Log.Debug( "2. Log Debug" );
It works ! You will see the messages.

My answer :

I think the problem come's more from Serilog Logging system that does not overring  Microsoft.Extensions.Logging.LogDebug
and LogTrace it's the same thing.

Mais au moment de publier ma réponse le site me répond tout bonnement "vous n'avez plus accès à la partie réponses avec ce compte d'utilisateur" !

Solution à LogDebug not working

Il s'agit de gérer le niveau de Trace. Voici ce qu'il faut faire dans le fichier de configuration : Application\appsettings.Development.json

  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "System": "Information",
      "Microsoft": "Information"
    },
    "Console": {
      "IncludeScopes": true
    }
  },

  "Serilog": {
    "Using": [ "Serilog.Sinks.RollingFile" ],
    "MinimumLevel": {
      "Default": "Verbose",
      "Override": {
        "System": "Warning",
        "Microsoft": "Warning"
      }
    }
  },


Et dans mon fichier : Application\appsettings.json

  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },

  "Serilog": {
    "Using": [ "Serilog.Sinks.RollingFile" ],
    "MinimumLevel": {
      "Default": "Warning",
      "Override": {
        "Microsoft.EntityFrameworkCore.Database.Command": "Error",
        "System": "Error",
        "Microsoft": "Warning",
      }
    },


Voilà et maintenant ça fonctionne "je vois" mes LogDebug.

PS : Si je ne vais pas directement dans StackOverflow écrire cette réponse c'est parce que leur système est un peu pourri et je n'accède plus aux réponses car j'ai donné une réponse par le passé qui n'a pas été notée ! Grrrr.