Apprendre à créer une application CRUD avec ASP.NET Core et Entity Framework Core,
Un tutoriel de Hinault Romaric

Le , par Hinault Romaric, Responsable .NET
Les modifications profondes qu’a subi ASP.NET Core peuvent sembler déconcertantes pour certains à première vue. Cependant, en dehors des changements dans les fichiers de configuration (abandon du XML pour du JSON), le modèle de programmation reste sensiblement le même.


Ce billet de blog s’adresse essentiellement aux débutants et pourra servir de base à ceux-ci pour démarrer avec leur première application ASP.NET Core avec Entity Framework Core. Nous allons utiliser dans ce billet l’approche Code First.

Vous devez disposer de Visual Studio 2015 Community Edition et .NET Core 1.0.0 - VS 2015 Tooling Preview 2.

Création du projet.

Créez un nouveau projet (SampleApp), en utilisant le modèle Web Application. Pour cela :

  • Lancez Visual Studio 2015 ;
  • Cliquez sur le menu Fichier, puis sur Nouveau et enfin Projet ;
  • Dans le menu de gauche, sélectionnez .NET Core ;
  • Choisissez le modèle de projet “ASP.NET Core Web Application (.NET Core)” ;
  • Entrez le nom du projet (SampleApp) et cliquez sur Ok ;
  • Dans la fenêtre qui va s’afficher, sélectionnez “Web Application” et cliquez sur Ok, pour créer le projet.



Ceci fait, ajoutez une référence à Entity Framework Core à partir de la console NuGet. Pour cela :
-cliquez sur le menu Outils, puis sur Gestionnaire de package NuGet et ensuite sur Console du Gestionnaire de package ;
- Dans la console qui va s’afficher, exécutez les deux commandes suivantes, pour installer Entity Framework Core et les outils rattachés.

Code : Sélectionner tout
1
2
3
Install-Package Microsoft.EntityFrameworkCore.SqlServer 
 
Install-Package Microsoft.EntityFrameworkCore.Tools –Pre

Ouvrez le fichier Project.json et copiez la ligne suivante dans la section “tools” :

Code : Sélectionner tout
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
Cette dernière devrait ressembler à ceci :

Code json : Sélectionner tout
1
2
3
4
5
6
"tools": { 
   "BundlerMinifier.Core": "2.0.238", 
   "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", 
   "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", 
   "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" 
 },

Création du Model

Créez un nouveau dossier “Models” dans votre projet (Clic droit sur le projet dans l’explorateur de solution, puis sur Nouveau, ensuite sur Dossier et saisir le nom du dossier).

Ajoutez dans ce dossier un nouveau fichier Student.cs (Clic droit sur le dossier dans l’explorateur de solution, puis sur Ajouter, ensuite Class et saisir le nom du fichier).

Dans ce fichier, ajoutez le code suivant :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Table("Student")] 
   public class Student 
   { 
       public int Id { get; set; } 
  
       [Required] 
       [StringLength(50)] 
       public string FirstName { get; set; } 
  
       [Required] 
       [StringLength(50)] 
       public string LastName { get; set; } 
  
       [Required] 
       [DataType(DataType.EmailAddress)] 
       [StringLength(50)] 
       public string Email { get; set; } 
   }

Vous devez ajouter les références suivantes :

Code c# : Sélectionner tout
1
2
using System.ComponentModel.DataAnnotations; 
using System.ComponentModel.DataAnnotations.Schema;

Vous venez de définir une table de votre base de données. Maintenant, vous allez créer le DbContext. Pour cela, vous devez ajouter un nouveau fichier SampleAppContext.cs au dossier Models de votre projet. Dans ce dernier, ajoutez le code suivant :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
public class SampleAppContext : DbContext 
   { 
  
       public SampleAppContext(DbContextOptions<SampleAppContext> options) 
           : base(options) 
       { } 
  
  
       public DbSet<Student> Students { get; set; } 
  
   }

Vous devez ajouter la référence suivante :

Code c# : Sélectionner tout
using Microsoft.EntityFrameworkCore;

Maintenant, vous allez utiliser l’injection des dépendances qu’offre ASP.NET Core pour enregistrer votre Context. Pour cela, ouvrez le fichier Startup.cs de votre projet. Ajoutez dans un premier temps les références suivantes :

Code c# : Sélectionner tout
1
2
using SampleApp.Models; 
using Microsoft.EntityFrameworkCore;

Dans la méthode ConfigureServices, ajoutez les lignes de code suivantes :

Code c# : Sélectionner tout
1
2
var connection = @"Server=(localdb)\mssqllocaldb;Database=StudentDB;Trusted_Connection=True;"; 
services.AddDbContext<SampleAppContext>(options => options.UseSqlServer(connection));

Enregistrez les modifications.

Génération de la base de données

Passons maintenant à la création de la base de données. Ouvrez à nouveau la console NuGet et exécutez les commandes suivantes :

Code : Sélectionner tout
1
2
3
Add-Migration InitDatabase 
 
Update-Database
La commande Add-Migration va créer dans votre projet un dossier “Migrations”, avec du code représentant le schéma de votre base de données. La commande Update-Database va utiliser ce code pour mettre à jour la base de données. Parce qu’elle n’existe pas, elle sera automatiquement créée.

Création du contrôleur

Ceci fait, exécutez successivement les commandes suivantes pour installer les packages qui permettront de disposer du scaffolding CRUD dans Visual Studio.

Code : Sélectionner tout
1
2
3
4
5
6
7
Install-Package Microsoft.EntityFrameworkCore.SqlServer 
 
Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Tools -Pre 
 
Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Core -Pre 
 
Install-Package Microsoft.VisualStudio.Web.CodeGenerators.Mvc -Pre
Ouvrez le fichier Project.json, ajoutez les données suivantes dans la section Tools et enregistrez :

Code json : Sélectionner tout
1
2
3
4
5
6
7
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": { 
     "version": "1.0.0-preview2-final", 
     "imports": [ 
       "portable-net45+win8+dnxcore50", 
       "portable-net45+win8" 
     ] 
   }
NB : Vous devez modifier "version": "1.0.0-preview2-final" afin que celle-ci corresponde à la version Microsoft.VisualStudio.Web.CodeGeneration.Tools dans la section dependencies.

Faites ensuite un clic droit sur le dossier “Controllers”, puis cliquez sur Ajouter, ensuite sur Controller. Dans la fenêtre qui va s’afficher, sélectionnez “MVC Controller with views, using Entity Framework”, puis cliquez sur “Ajouter”. Dans la fenêtre qui va s’afficher, sélectionnez le modèle (Student), puis le Data Context (SampleAppContext), et cliquez sur Ajouter :


Le contrôleur sera généré avec des actions pour la consultation, la création, la modification et la suppression. Les vues correspondantes seront automatiquement ajoutées :



Si vous ouvrez le fichier StudentsController.cs, vous aurez le code 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
public class StudentsController : Controller 
   { 
       private readonly SampleAppContext _context; 
  
       public StudentsController(SampleAppContext context) 
       { 
           _context = context;     
       } 
  
       // GET: Students 
       public async Task<IActionResult> Index() 
       { 
           return View(await _context.Students.ToListAsync()); 
       } 
  
       // GET: Students/Details/5 
       public async Task<IActionResult> Details(int? id) 
       { 
           if (id == null) 
           { 
               return NotFound(); 
           } 
  
           var student = await _context.Students.SingleOrDefaultAsync(m => m.Id == id); 
           if (student == null) 
           { 
               return NotFound(); 
           } 
  
           return View(student); 
       } 
  
       // GET: Students/Create 
       public IActionResult Create() 
       { 
           return View(); 
       } 
  
       // POST: Students/Create 
       // To protect from overposting attacks, please enable the specific properties you want to bind to, for  
       // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
       [HttpPost] 
       [ValidateAntiForgeryToken] 
       public async Task<IActionResult> Create([Bind("Id,Email,FirstName,LastName")] Student student) 
       { 
           if (ModelState.IsValid) 
           { 
               _context.Add(student); 
               await _context.SaveChangesAsync(); 
               return RedirectToAction("Index"); 
           } 
           return View(student); 
       } 
  
       // GET: Students/Edit/5 
       public async Task<IActionResult> Edit(int? id) 
       { 
           if (id == null) 
           { 
               return NotFound(); 
           } 
  
           var student = await _context.Students.SingleOrDefaultAsync(m => m.Id == id); 
           if (student == null) 
           { 
               return NotFound(); 
           } 
           return View(student); 
       } 
  
       // POST: Students/Edit/5 
       // To protect from overposting attacks, please enable the specific properties you want to bind to, for  
       // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
       [HttpPost] 
       [ValidateAntiForgeryToken] 
       public async Task<IActionResult> Edit(int id, [Bind("Id,Email,FirstName,LastName")] Student student) 
       { 
           if (id != student.Id) 
           { 
               return NotFound(); 
           } 
  
           if (ModelState.IsValid) 
           { 
               try 
               { 
                   _context.Update(student); 
                   await _context.SaveChangesAsync(); 
               } 
               catch (DbUpdateConcurrencyException) 
               { 
                   if (!StudentExists(student.Id)) 
                   { 
                       return NotFound(); 
                   } 
                   else 
                   { 
                       throw; 
                   } 
               } 
               return RedirectToAction("Index"); 
           } 
           return View(student); 
       } 
  
       // GET: Students/Delete/5 
       public async Task<IActionResult> Delete(int? id) 
       { 
           if (id == null) 
           { 
               return NotFound(); 
           } 
  
           var student = await _context.Students.SingleOrDefaultAsync(m => m.Id == id); 
           if (student == null) 
           { 
               return NotFound(); 
           } 
  
           return View(student); 
       } 
  
       // POST: Students/Delete/5 
       [HttpPost, ActionName("Delete")] 
       [ValidateAntiForgeryToken] 
       public async Task<IActionResult> DeleteConfirmed(int id) 
       { 
           var student = await _context.Students.SingleOrDefaultAsync(m => m.Id == id); 
           _context.Students.Remove(student); 
           await _context.SaveChangesAsync(); 
           return RedirectToAction("Index"); 
       } 
  
       private bool StudentExists(int id) 
       { 
           return _context.Students.Any(e => e.Id == id); 
       } 
   }

Exécutez votre application. Dans le lien qui va s’afficher dans le navigateur, saisissez à la suite /students/create. Vous aurez la page suivante:


Vous venez de créer votre première application CRUD ASP.NET Core MVC avec Entity Framework Core. Vous pouvez désormais continuer à l’enrichir en fonctionnalités.


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster un commentaire

Avatar de patmaba patmaba - Membre habitué https://www.developpez.com
le 14/09/2016 à 10:14
public string FristName { get; set; }

c'est pas FristName mais FirstName

public
string FirstName { get; set; }
Avatar de Hinault Romaric Hinault Romaric - Responsable .NET https://www.developpez.com
le 16/09/2016 à 18:48
Citation Envoyé par patmaba;bt3104
public string FristName { get; set; }

c'est pas FristName mais FirstName

public
string FirstName { get; set; }

Une erreur de frappe. C'est corrigé.

Avatar de speed84500 speed84500 - Nouveau Candidat au Club https://www.developpez.com
le 17/09/2016 à 11:06
Je découvre ASP.NET avec ce tuto et cette erreur apparaît au moment de la génération du contrôleur.

Avatar de Hinault Romaric Hinault Romaric - Responsable .NET https://www.developpez.com
le 17/09/2016 à 14:41
Citation Envoyé par speed84500;bt3122
Je découvre ASP.NET avec ce tuto et cette erreur apparaît au moment de la génération du contrôleur.


Peux-tu poster le contenu de ton fichier project.json?
Avatar de speed84500 speed84500 - Nouveau Candidat au Club https://www.developpez.com
le 17/09/2016 à 17:55
Citation Envoyé par Hinault Romaric;bt3123
Peux-tu poster le contenu de ton fichier project.json?

project.json :
Code JSON : 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
{ 
  "dependencies": { 
    "Microsoft.NETCore.App": { 
      "version": "1.0.1", 
      "type": "platform" 
    }, 
    "Microsoft.ApplicationInsights.AspNetCore": "1.0.0", 
    "Microsoft.AspNetCore.Diagnostics": "1.0.0", 
    "Microsoft.AspNetCore.Mvc": "1.0.1", 
    "Microsoft.AspNetCore.Razor.Tools": { 
      "version": "1.0.0-preview2-final", 
      "type": "build" 
    }, 
    "Microsoft.AspNetCore.Routing": "1.0.1", 
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", 
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", 
    "Microsoft.AspNetCore.StaticFiles": "1.0.0", 
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", 
    "Microsoft.Extensions.Configuration.Json": "1.0.0", 
    "Microsoft.Extensions.Logging": "1.0.0", 
    "Microsoft.Extensions.Logging.Console": "1.0.0", 
    "Microsoft.Extensions.Logging.Debug": "1.0.0", 
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", 
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0", 
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", 
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", 
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": "1.0.0-preview2-update1", 
    "Microsoft.VisualStudio.Web.CodeGeneration.Core": "1.0.0-preview2-update1", 
    "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": "1.0.0-preview2-update1" 
  }, 
  
  "tools": { 
    "BundlerMinifier.Core": "2.0.238", 
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", 
    "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", 
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final", 
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { 
      "version": "1.0.0-preview2-final", 
      "imports": [ 
        "portable-net45+win8+dnxcore50", 
        "portable-net45+win8" 
      ] 
    } 
  }, 
  
  "frameworks": { 
    "netcoreapp1.0": { 
      "imports": [ 
        "dotnet5.6", 
        "portable-net45+win8" 
      ] 
    } 
  }, 
  
  "buildOptions": { 
    "emitEntryPoint": true, 
    "preserveCompilationContext": true 
  }, 
  
  "runtimeOptions": { 
    "configProperties": { 
      "System.GC.Server": true 
    } 
  }, 
  
  "publishOptions": { 
    "include": [ 
      "wwwroot", 
      "**/*.cshtml", 
      "appsettings.json", 
      "web.config" 
    ] 
  }, 
  
  "scripts": { 
    "prepublish": [ "bower install", "dotnet bundle" ], 
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] 
  } 
}
Avatar de Hinault Romaric Hinault Romaric - Responsable .NET https://www.developpez.com
le 19/09/2016 à 14:39
Bonjour,

Remplace le contenu de ton JSON avec le suivant :

Code : 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 
{ 
  "dependencies": { 
    "Microsoft.NETCore.App": { 
      "version": "1.0.1", 
      "type": "platform" 
    }, 
    "Microsoft.ApplicationInsights.AspNetCore": "1.0.0", 
    "Microsoft.AspNetCore.Diagnostics": "1.0.0", 
    "Microsoft.AspNetCore.Mvc": "1.0.1", 
    "Microsoft.AspNetCore.Razor.Tools": { 
      "version": "1.0.0-preview2-final", 
      "type": "build" 
    }, 
    "Microsoft.AspNetCore.Routing": "1.0.1", 
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", 
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", 
    "Microsoft.AspNetCore.StaticFiles": "1.0.0", 
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", 
    "Microsoft.Extensions.Configuration.Json": "1.0.0", 
    "Microsoft.Extensions.Logging": "1.0.0", 
    "Microsoft.Extensions.Logging.Console": "1.0.0", 
    "Microsoft.Extensions.Logging.Debug": "1.0.0", 
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", 
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0", 
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", 
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", 
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": "1.0.0-preview2-update1", 
    "Microsoft.VisualStudio.Web.CodeGeneration.Core": "1.0.0-preview2-update1", 
    "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": "1.0.0-preview2-update1" 
  }, 
 
  "tools": { 
    "BundlerMinifier.Core": "2.0.238", 
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", 
    "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", 
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final", 
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { 
      "version": "1.0.0-preview2-update1", 
      "imports": [ 
        "portable-net45+win8+dnxcore50", 
        "portable-net45+win8" 
      ] 
    } 
  }, 
 
  "frameworks": { 
    "netcoreapp1.0": { 
      "imports": [ 
        "dotnet5.6", 
        "portable-net45+win8" 
      ] 
    } 
  }, 
 
  "buildOptions": { 
    "emitEntryPoint": true, 
    "preserveCompilationContext": true 
  }, 
 
  "runtimeOptions": { 
    "configProperties": { 
      "System.GC.Server": true 
    } 
  }, 
 
  "publishOptions": { 
    "include": [ 
      "wwwroot", 
      "**/*.cshtml", 
      "appsettings.json", 
      "web.config" 
    ] 
  }, 
 
  "scripts": { 
    "prepublish": [ "bower install", "dotnet bundle" ], 
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] 
  } 
}
En effet la version de Microsoft.VisualStudio.Web.CodeGeneration.Tools dans la section dependencies ne correspondait pas à celle de la section tools. C'est de ma faute, car je demande de copier celle que je spécifie dans mon tutoriel, pourtant entre temps il peut avoir des évolutions. Ce qui a été le cas pour toi.
Offres d'emploi IT
Ingénieur Développement Logiciels pour Produits Optroniques H/F
Safran - Ile de France - Éragny (95610)
Chef de Projet SSI H/F
Safran - Ile de France - Massy (91300)
Responsable développement logiciel Drone H/F
Safran - Ile de France - Éragny (95610)

Voir plus d'offres Voir la carte des offres IT
Contacter le responsable de la rubrique Accueil