Partager via


Tutoriel : Implémenter des fonctionnalités CRUD avec Entity Framework dans ASP.NET MVC

Dans le tutoriel précédent, vous avez créé une application MVC qui stocke et affiche des données à l’aide d’Entity Framework (EF) 6 et SQL Server LocalDB. Dans ce tutoriel, vous passez en revue et personnalisez le code de création, de lecture, de mise à jour, de suppression (CRUD) que la structure MVC crée automatiquement pour vous dans les contrôleurs et les vues.

Remarque

Il est courant d’implémenter le modèle de référentiel pour créer une couche d’abstraction entre votre contrôleur et la couche d’accès aux données. Pour simplifier et concentrer ces didacticiels sur l’apprentissage de l’utilisation d’EF 6 lui-même, ils n’utilisent pas de référentiels. Pour plus d’informations sur l’implémentation de référentiels, consultez la ASP.NET Carte de contenu d’accès aux données.

Voici des exemples de pages web que vous créez :

Capture d’écran de la page de détails de l’étudiant.

Capture d’écran de la page de création d’étudiant.

Capture d’écran de la page de suppression de l’étudiant.

Dans ce tutoriel, vous allez :

  • Créer une page Détails
  • Mettre à jour la page Create
  • Mettre à jour la méthode HttpPost Edit
  • Mettre à jour la page Delete
  • Fermer les connexions de base de données
  • Gérer les transactions

Prérequis

Créer une page Détails

Le code généré automatiquement pour la page Students Index n’a pas quitté la Enrollments propriété, car cette propriété contient une collection. Dans la Details page, vous allez afficher le contenu de la collection dans une table HTML.

Dans Controllers\StudentController.cs, la méthode d’action de la Details vue utilise la méthode Find pour récupérer une seule Student entité.

public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Student student = db.Students.Find(id);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

La valeur de clé est passée à la méthode en tant que id paramètre et provient des données de routage dans le lien hypertexte Détails de la page Index.

Conseil : Acheminer les données

Les données de routage sont des données que le classeur de modèles trouvé dans un segment d’URL spécifié dans la table de routage. Par exemple, l’itinéraire par défaut spécifie , actionet id les segments controller:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Dans l’URL suivante, l’itinéraire par défaut est mappé Instructor en tant controllerque , Index comme le action et 1 comme le id; il s’agit de valeurs de données de routage.

http://localhost:1230/Instructor/Index/1?courseID=2021

?courseID=2021 est une valeur de chaîne de requête. Le classeur de modèles fonctionne également si vous passez la id valeur de chaîne de requête :

http://localhost:1230/Instructor/Index?id=1&CourseID=2021

Les URL sont créées par ActionLink des instructions dans la vue Razor. Dans le code suivant, le id paramètre correspond à l’itinéraire par défaut. Il est donc id ajouté aux données de routage.

@Html.ActionLink("Select", "Index", new { id = item.PersonID  })

Dans le code suivant, courseID ne correspond pas à un paramètre dans l’itinéraire par défaut. Il est donc ajouté en tant que chaîne de requête.

@Html.ActionLink("Select", "Index", new { courseID = item.CourseID })

Pour créer la page Détails

  1. Ouvrez Views\Student\Details.cshtml.

    Chaque champ s’affiche à l’aide d’un DisplayFor assistance, comme illustré dans l’exemple suivant :

    <dt>
        @Html.DisplayNameFor(model => model.LastName)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.LastName)
    </dd>
    
  2. Après le EnrollmentDate champ et juste avant la balise de fermeture </dl> , ajoutez le code mis en surbrillance pour afficher une liste d’inscriptions, comme illustré dans l’exemple suivant :

    <dt>
                @Html.DisplayNameFor(model => model.EnrollmentDate)
            </dt>
    
            <dd>
                @Html.DisplayFor(model => model.EnrollmentDate)
            </dd>
            <dt>
                @Html.DisplayNameFor(model => model.Enrollments)
            </dt>
            <dd>
                <table class="table">
                    <tr>
                        <th>Course Title</th>
                        <th>Grade</th>
                    </tr>
                    @foreach (var item in Model.Enrollments)
                    {
                        <tr>
                            <td>
                                @Html.DisplayFor(modelItem => item.Course.Title)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Grade)
                            </td>
                        </tr>
                    }
                </table>
            </dd>
        </dl>
    </div>
    <p>
        @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
        @Html.ActionLink("Back to List", "Index")
    </p>
    

    Si la mise en retrait du code est incorrecte après avoir collé le code, appuyez sur Ctrl+K, Ctrl+D pour la mettre en forme.

    Ce code parcourt en boucle les entités dans la propriété de navigation Enrollments. Pour chaque Enrollment entité de la propriété, elle affiche le titre du cours et la note. Le titre du cours est récupéré à partir de l’entité Course stockée dans la Course propriété de navigation de l’entité Enrollments . Toutes ces données sont récupérées automatiquement à partir de la base de données quand elles sont nécessaires. En d’autres termes, vous utilisez le chargement différé ici. Vous n’avez pas spécifié de chargement impatient pour la Courses propriété de navigation, de sorte que les inscriptions n’ont pas été récupérées dans la même requête que celles qui ont obtenu les étudiants. Au lieu de cela, la première fois que vous essayez d’accéder à la Enrollments propriété de navigation, une nouvelle requête est envoyée à la base de données pour récupérer les données. Vous pouvez en savoir plus sur le chargement différé et le chargement impatient dans le didacticiel Lire les données associées plus loin dans cette série.

  3. Ouvrez la page Détails en démarrant le programme (Ctrl+F5), en sélectionnant l’onglet Étudiants, puis en cliquant sur le lien Détails pour Alexander Carson. (Si vous appuyez sur Ctrl+F5 pendant que le fichier Details.cshtml est ouvert, vous obtenez une erreur HTTP 400. Cela est dû au fait que Visual Studio tente d’exécuter la page Détails, mais qu’il n’a pas été atteint à partir d’un lien qui spécifie l’étudiant à afficher. Si cela se produit, supprimez « Student/Details » de l’URL et réessayez, ou fermez le navigateur, cliquez avec le bouton droit sur le projet, puis cliquez sur Afficher>l’affichage dans le navigateur.)

    Vous voyez la liste des cours et notes pour l’étudiant sélectionné.

  4. Fermez le navigateur.

Mettre à jour la page Create

  1. Dans Controllers\StudentController.cs, remplacez la HttpPostAttribute Create méthode d’action par le code suivant. Ce code ajoute un try-catch bloc et supprime ID de l’attribut BindAttribute pour la méthode générée :

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "LastName, FirstMidName, EnrollmentDate")]Student student)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.Students.Add(student);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
        }
        catch (DataException /* dex */)
        {
            //Log the error (uncomment dex variable name and add a line here to write a log.
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
        }
        return View(student);
    }
    

    Ce code ajoute l’entité Student créée par le classeur de modèles MVC ASP.NET au Students jeu d’entités, puis enregistre les modifications apportées à la base de données. Le classeur de modèles fait référence à la fonctionnalité MVC ASP.NET qui facilite l’utilisation des données soumises par un formulaire ; un classeur de modèles convertit les valeurs de formulaire publiées en types CLR et les transmet à la méthode d’action dans les paramètres. Dans ce cas, le classeur de modèles instancie une Student entité pour vous à l’aide de valeurs de propriété de la Form collection.

    Vous avez supprimé ID de l’attribut Bind, car ID est la valeur de clé primaire définie automatiquement par SQL Server lors de l’insertion de la ligne. L’entrée de l’utilisateur ne définit pas la ID valeur.

    Avertissement de sécurité : l’attribut ValidateAntiForgeryToken permet d’empêcher les attaques de falsification de requête intersite. Elle nécessite une instruction correspondante Html.AntiForgeryToken() dans la vue, que vous verrez ultérieurement.

    L’attribut Bind est un moyen de se protéger contre la sur-publication dans les scénarios de création. Par exemple, supposons que l’entité Student inclut une Secret propriété que vous ne souhaitez pas définir cette page web.

    public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }
        public string Secret { get; set; }
    
        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
    

    Même si vous n’avez pas de Secret champ sur la page web, un pirate peut utiliser un outil tel que fiddler ou écrire un code JavaScript pour publier une Secret valeur de formulaire. Sans l’attribut BindAttribute limitant les champs utilisés par le classeur de modèles lors de la création d’une Student instance, le classeur de modèles récupère cette Secret valeur de formulaire et l’utilise pour créer l’instance Student d’entité. Ensuite, la valeur spécifiée par le hacker pour le champ de formulaire Secret, quelle qu’elle soit, est mise à jour dans la base de données. L’image suivante montre l’outil fiddler qui ajoute le Secret champ (avec la valeur « OverPost ») aux valeurs de formulaire publiées.

    Capture d’écran montrant l’onglet Composer. Dans le coin supérieur droit, l’exécution est en rouge. Dans le coin inférieur droit, le secret est égal à Over Post en rouge.

    La valeur « OverPost » serait correctement ajoutée à la propriété Secret de la ligne insérée, même si vous n’aviez jamais prévu que la page web puisse définir cette propriété.

    Il est préférable d’utiliser le Include paramètre avec l’attribut Bind pour répertorier explicitement les champs. Il est également possible d’utiliser le Exclude paramètre pour bloquer les champs que vous souhaitez exclure. La raison Include est plus sécurisée : lorsque vous ajoutez une nouvelle propriété à l’entité, le nouveau champ n’est pas automatiquement protégé par une Exclude liste.

    Vous pouvez empêcher le surpostage dans les scénarios de modification en lisant d’abord l’entité à partir de la base de données, puis en appelant TryUpdateModel, en passant une liste de propriétés autorisées explicite. Il s’agit de la méthode utilisée dans ces didacticiels.

    Une autre façon d’empêcher le surpostage préféré par de nombreux développeurs consiste à utiliser des modèles d’affichage plutôt que des classes d’entité avec la liaison de modèle. Incluez seulement les propriétés que vous voulez mettre à jour dans le modèle de vue. Une fois le classeur de modèles MVC terminé, copiez les propriétés du modèle d’affichage dans l’instance d’entité, éventuellement à l’aide d’un outil tel que AutoMapper. Utilisez la base de données. Entrée sur l’instance d’entité pour définir son état sur Inchangé, puis définissez Property(« PropertyName »). IsModified à true sur chaque propriété d’entité incluse dans le modèle d’affichage. Cette méthode fonctionne à la fois dans les scénarios de modification et de création.

    Autre que l’attribut Bind , le try-catch bloc est la seule modification que vous avez apportée au code généré. Si une exception qui dérive de DataException est interceptée lors de l’enregistrement des modifications, un message d’erreur générique est affiché. Les exceptions DataException sont parfois dues à quelque chose d’externe à l’application et non pas à une erreur de programmation : il est donc conseillé à l’utilisateur de réessayer. Bien que ceci ne soit pas implémenté dans cet exemple, une application destinée à la production doit consigner l’exception. Pour plus d’informations, consultez la section Journal pour obtenir un aperçu de Surveillance et télémétrie (génération d’applications Cloud du monde réel avec Azure).

    Le code dans Views\Student\Create.cshtml est similaire à ce que vous avez vu dans Details.cshtml, sauf que EditorFor les ValidationMessageFor helpers sont utilisés pour chaque champ au lieu de DisplayFor. Voici le code correspondant :

    <div class="form-group">
        @Html.LabelFor(model => model.LastName, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
    </div>
    

    Create.cshtml inclut @Html.AntiForgeryToken()également , qui fonctionne avec l’attribut ValidateAntiForgeryToken dans le contrôleur pour empêcher les attaques de falsification de requête intersite.

    Aucune modification n’est requise dans Create.cshtml.

  2. Exécutez la page en démarrant le programme, en sélectionnant l’onglet Étudiants , puis en cliquant sur Créer nouveau.

  3. Entrez des noms et une date non valide, puis cliquez sur Créer pour afficher le message d’erreur.

    Il s’agit de la validation côté serveur que vous obtenez par défaut. Dans un didacticiel ultérieur, vous allez découvrir comment ajouter des attributs qui génèrent du code pour la validation côté client. Le code mis en surbrillance suivant montre la vérification de validation du modèle dans la méthode Create .

    if (ModelState.IsValid)
    {
        db.Students.Add(student);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    
  4. Changez la date en une valeur valide, puis cliquez sur Create pour voir apparaître le nouvel étudiant dans la page Index.

  5. Fermez le navigateur.

Mettre à jour la méthode HttpPost Edit

  1. Remplacez la méthode d’action HttpPostAttribute Edit par le code suivant :

    [HttpPost, ActionName("Edit")]
    [ValidateAntiForgeryToken]
    public ActionResult EditPost(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var studentToUpdate = db.Students.Find(id);
        if (TryUpdateModel(studentToUpdate, "",
           new string[] { "LastName", "FirstMidName", "EnrollmentDate" }))
        {
            try
            {
                db.SaveChanges();
    
                return RedirectToAction("Index");
            }
            catch (DataException /* dex */)
            {
                //Log the error (uncomment dex variable name and add a line here to write a log.
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
            }
        }
        return View(studentToUpdate);
    }
    

    Remarque

    Dans Controllers\StudentController.cs, la HttpGet Edit méthode (celle sans l’attribut HttpPost ) utilise la Find méthode pour récupérer l’entité sélectionnée Student , comme vous l’avez vu dans la Details méthode. Vous n’avez pas besoin de modifier cette méthode.

    Ces modifications implémentent une bonne pratique de sécurité pour empêcher le surpostage, l’échafaudeur a généré un Bind attribut et ajouté l’entité créée par le classeur de modèles à l’ensemble d’entités avec un indicateur modifié. Ce code n’est plus recommandé, car l’attribut Bind efface toutes les données préexistantes dans les champs non répertoriés dans le Include paramètre. À l’avenir, l’échafaudeur du contrôleur MVC sera mis à jour afin qu’il ne génère Bind pas d’attributs pour les méthodes Edit.

    Le nouveau code lit l’entité existante et appelle TryUpdateModel pour mettre à jour les champs à partir de l’entrée utilisateur dans les données de formulaire publiées. Le suivi automatique des modifications d’Entity Framework définit l’indicateur EntityState.Modified sur l’entité. Lorsque la méthode SaveChanges est appelée, l’indicateur Modified provoque la création d’instructions SQL par Entity Framework pour mettre à jour la ligne de base de données. Les conflits d’accès concurrentiel sont ignorés et toutes les colonnes de la ligne de base de données sont mises à jour, y compris celles que l’utilisateur n’a pas changé. (Un didacticiel ultérieur montre comment gérer les conflits d’accès concurrentiel et si vous souhaitez uniquement que des champs individuels soient mis à jour dans la base de données, vous pouvez définir l’entité sur EntityState.Unchanged et définissez des champs individuels sur EntityState.Modified.)

    Pour empêcher le surpostage, les champs que vous souhaitez mettre à jour par la page Modifier sont répertoriés dans les TryUpdateModel paramètres. Actuellement, vous ne protégez aucun champ supplémentaire, mais le fait de répertorier les champs que vous voulez que le classeur de modèles lie garantit que si vous ajoutez ultérieurement des champs au modèle de données, ils seront automatiquement protégés jusqu’à ce que vous les ajoutiez explicitement ici.

    En raison de ces modifications, la signature de méthode de la méthode HttpPost Edit est la même que la méthode HttpGet edit ; vous avez donc renommé la méthode EditPost.

    Conseil

    États d’entité et méthodes Attach et SaveChanges

    Le contexte de base de données effectue le suivi de la synchronisation ou non des entités en mémoire avec leurs lignes correspondantes dans la base de données, et ces informations déterminent ce qui se passe quand vous appelez la méthode SaveChanges. Par exemple, lorsque vous transmettez une nouvelle entité à la méthode Add , l’état de cette entité est défini Addedsur . Ensuite, lorsque vous appelez la méthode SaveChanges , le contexte de base de données émet une commande SQL INSERT .

    Une entité peut être dans l’un des états suivants :

    • Added. L’entité n’existe pas encore dans la base de données. La SaveChanges méthode doit émettre une INSERT instruction.
    • Unchanged. La méthode SaveChanges ne doit rien faire avec cette entité. Quand vous lisez une entité dans la base de données, l’entité a d’abord cet état.
    • Modified. Tout ou partie des valeurs de propriété de l’entité ont été modifiées. La SaveChanges méthode doit émettre une UPDATE instruction.
    • Deleted. L’entité a été marquée pour suppression. La SaveChanges méthode doit émettre une DELETE instruction.
    • Detached. L’entité n’est pas suivie par le contexte de base de données.

    Dans une application de poste de travail, les changements d’état sont généralement définis automatiquement. Dans un type d’application de bureau, vous lisez une entité et apportez des modifications à certaines de ses valeurs de propriété. Son état passe alors automatiquement à Modified. Ensuite, lorsque vous appelez SaveChanges, Entity Framework génère une instruction SQL UPDATE qui met à jour uniquement les propriétés réelles que vous avez modifiées.

    La nature déconnectée des applications web n’autorise pas cette séquence continue. DbContext qui lit une entité est supprimée après le rendu d’une page. Lorsque la HttpPost Edit méthode d’action est appelée, une nouvelle requête est effectuée et vous disposez d’une nouvelle instance de DbContext. Vous devez donc définir manuellement l’état Modified. de l’entité sur Then lorsque vous appelez SaveChanges, Entity Framework met à jour toutes les colonnes de la ligne de base de données, car le contexte n’a aucun moyen de savoir quelles propriétés vous avez modifiées.

    Si vous souhaitez que l’instruction SQL Update met à jour uniquement les champs que l’utilisateur a réellement modifiés, vous pouvez enregistrer les valeurs d’origine d’une certaine manière (comme les champs masqués) afin qu’elles soient disponibles lorsque la HttpPost Edit méthode est appelée. Vous pouvez ensuite créer une Student entité à l’aide des valeurs d’origine, appeler la Attach méthode avec cette version d’origine de l’entité, mettre à jour les valeurs de l’entité vers les nouvelles valeurs, puis appeler SaveChanges. Pour plus d’informations, consultez Les états d’entité et SaveChanges et Les données locales.

    Le code HTML et Razor dans Views\Student\Edit.cshtml est similaire à ce que vous avez vu dans Create.cshtml et aucune modification n’est requise.

  2. Exécutez la page en démarrant le programme, en sélectionnant l’onglet Étudiants , puis en cliquant sur un lien hypertexte Modifier .

  3. Changez quelques données et cliquez sur Save. Vous voyez les données modifiées dans la page Index.

  4. Fermez le navigateur.

Mettre à jour la page Delete

Dans Controllers\StudentController.cs, le code de modèle de la HttpGetAttribute Delete méthode utilise la Find méthode pour récupérer l’entité sélectionnéeStudent, comme vous l’avez vu dans les méthodes et Edit les Details méthodes. Cependant, pour implémenter un message d’erreur personnalisé quand l’appel à SaveChanges échoue, vous devez ajouter des fonctionnalités à cette méthode et à sa vue correspondante.

Comme vous l’avez vu pour les opérations de mise à jour et de création, les opérations de suppression nécessitent deux méthodes d’action. La méthode appelée en réponse à une requête GET affiche une vue qui permet à l’utilisateur d’approuver ou d’annuler l’opération de suppression. Si l’utilisateur l’approuve, une demande POST est créée. Lorsque cela se produit, la HttpPost Delete méthode est appelée, puis cette méthode effectue réellement l’opération de suppression.

Vous allez ajouter un try-catch bloc à la HttpPostAttribute Delete méthode pour gérer les erreurs qui peuvent se produire lorsque la base de données est mise à jour. Si une erreur se produit, la HttpPostAttribute Delete méthode appelle la HttpGetAttribute Delete méthode, en lui transmettant un paramètre qui indique qu’une erreur s’est produite. La HttpGetAttribute Delete méthode réaffiche ensuite la page de confirmation avec le message d’erreur, ce qui permet à l’utilisateur d’annuler ou de réessayer.

  1. Remplacez la méthode d’action HttpGetAttribute Delete par le code suivant, qui gère le rapport d’erreurs :

    public ActionResult Delete(int? id, bool? saveChangesError=false)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        if (saveChangesError.GetValueOrDefault())
        {
            ViewBag.ErrorMessage = "Delete failed. Try again, and if the problem persists see your system administrator.";
        }
        Student student = db.Students.Find(id);
        if (student == null)
        {
            return HttpNotFound();
        }
        return View(student);
    }
    

    Ce code accepte un paramètre facultatif qui indique si la méthode a été appelée après un échec d’enregistrement des modifications. Ce paramètre est false lorsque la HttpGet Delete méthode est appelée sans échec précédent. Lorsqu’elle est appelée par la HttpPost Delete méthode en réponse à une erreur de mise à jour de base de données, le paramètre est true et un message d’erreur est transmis à la vue.

  2. Remplacez la HttpPostAttribute Delete méthode d’action (nommée DeleteConfirmed) par le code suivant, qui effectue l’opération de suppression réelle et intercepte les erreurs de mise à jour de base de données.

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Delete(int id)
    {
        try
        {
            Student student = db.Students.Find(id);
            db.Students.Remove(student);
            db.SaveChanges();
        }
        catch (DataException/* dex */)
        {
            //Log the error (uncomment dex variable name and add a line here to write a log.
            return RedirectToAction("Delete", new { id = id, saveChangesError = true });
        }
        return RedirectToAction("Index");
    }
    

    Ce code récupère l’entité sélectionnée, puis appelle la méthode Remove pour définir l’état Deletedde l’entité sur . Lorsque SaveChanges est appelée, une commande SQL DELETE est générée. Vous avez également changé le nom de la méthode d’action de DeleteConfirmed en Delete. Code généré automatiquement nommé la HttpPost Delete méthode DeleteConfirmed pour donner à la HttpPost méthode une signature unique. (Le CLR nécessite des méthodes surchargées pour avoir des paramètres de méthode différents.) Maintenant que les signatures sont uniques, vous pouvez respecter la convention MVC et utiliser le même nom pour les méthodes de suppression et HttpGet de HttpPost suppression.

    Si l’amélioration des performances dans une application à volume élevé est une priorité, vous pouvez éviter une requête SQL inutile pour récupérer la ligne en remplaçant les lignes de code qui appellent le Find code et Remove les méthodes par le code suivant :

    Student studentToDelete = new Student() { ID = id };
    db.Entry(studentToDelete).State = EntityState.Deleted;
    

    Ce code instancie une Student entité en utilisant uniquement la valeur de clé primaire, puis définit l’état de Deletedl’entité sur . C’est tout ce dont a besoin Entity Framework pour pouvoir supprimer l’entité.

    Comme indiqué, la HttpGet Delete méthode ne supprime pas les données. L’exécution d’une opération de suppression en réponse à une requête GET (ou à ce titre, l’exécution d’une opération de modification, l’opération de création ou toute autre opération qui modifie les données) crée un risque de sécurité. Pour plus d’informations, consultez ASP.NET conseil MVC #46 — N’utilisez pas de liens de suppression, car ils créent des trous de sécurité sur le blog de Stephen Walther.

  3. Dans Views\Student\Delete.cshtml, ajoutez un message d’erreur entre le h2 titre et le h3 titre, comme illustré dans l’exemple suivant :

    <h2>Delete</h2>
    <p class="error">@ViewBag.ErrorMessage</p>
    <h3>Are you sure you want to delete this?</h3>
    
  4. Exécutez la page en démarrant le programme, en sélectionnant l’onglet Étudiants , puis en cliquant sur un lien hypertexte Supprimer .

  5. Choisissez Supprimer sur la page qui indique Êtes-vous sûr de vouloir le supprimer ?.

    La page Index s’affiche sans l’étudiant supprimé. (Vous verrez un exemple de code de gestion des erreurs en action dans le didacticiel d’accès concurrentiel.)

Fermer les connexions de base de données

Pour fermer les connexions de base de données et libérer les ressources qu’ils contiennent dès que possible, supprimez l’instance de contexte lorsque vous l’avez terminé. C’est pourquoi le code généré automatiquement fournit une méthode Dispose à la fin de la StudentController classe dans StudentController.cs, comme illustré dans l’exemple suivant :

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        db.Dispose();
    }
    base.Dispose(disposing);
}

La classe de base Controller implémente déjà l’interface IDisposable . Ce code ajoute simplement une substitution à la Dispose(bool) méthode pour supprimer explicitement l’instance de contexte.

Gérer les transactions

Par défaut, Entity Framework implémente implicitement les transactions. Dans les scénarios où vous apportez des modifications à plusieurs lignes ou tables, puis appelez SaveChanges, Entity Framework garantit automatiquement que toutes vos modifications réussissent ou échouent. Si certaines modifications sont effectuées en premier puis qu’une erreur se produit, ces modifications sont automatiquement annulées. Pour les scénarios où vous avez besoin d’un contrôle supplémentaire( par exemple, si vous souhaitez inclure des opérations effectuées en dehors d’Entity Framework dans une transaction), consultez Utilisation des transactions.

Obtenir le code

Télécharger le projet terminé

Ressources supplémentaires

Vous disposez maintenant d’un ensemble complet de pages qui effectuent des opérations CRUD simples pour Student les entités. Vous avez utilisé des helpers MVC pour générer des éléments d’interface utilisateur pour les champs de données. Pour plus d’informations sur les helpers MVC, consultez Rendu d’un formulaire à l’aide de l’aide HTML (l’article concerne MVC 3, mais il est toujours pertinent pour MVC 5).

Vous trouverez des liens vers d’autres ressources EF 6 dans ASP.NET Accès aux données - Ressources recommandées.

Étapes suivantes

Dans ce tutoriel, vous allez :

  • Page Détails créé
  • Mettre à jour la page Create
  • Mise à jour de la méthode HttpPost Edit
  • Mettre à jour la page Delete
  • Connexions de base de données fermées
  • Transactions gérées

Passez à l’article suivant pour apprendre à ajouter le tri, le filtrage et la pagination au projet.