Liaison de données dans ASP.NET CoreModel Binding in ASP.NET Core

Par Rachel AppelBy Rachel Appel

Introduction à la liaison de modèleIntroduction to model binding

La liaison de modèle dans ASP.NET Core MVC mappe les données des requêtes HTTP à des paramètres de méthode d’action.Model binding in ASP.NET Core MVC maps data from HTTP requests to action method parameters. Les paramètres peuvent être des types simples, comme des chaînes, des entiers ou des nombres à virgule flottante, ou ils peuvent être des types complexes.The parameters may be simple types such as strings, integers, or floats, or they may be complex types. Il s’agit d’une fonctionnalité intéressante de MVC, car le mappage des données entrantes à une contrepartie est un scénario souvent répété, quelle que soit la taille ou la complexité des données.This is a great feature of MVC because mapping incoming data to a counterpart is an often repeated scenario, regardless of size or complexity of the data. MVC résout ce problème en rendant la liaison transparente : les développeurs ne doivent pas continuer à réécrire une version légèrement différente de ce même code dans chaque application.MVC solves this problem by abstracting binding away so developers don't have to keep rewriting a slightly different version of that same code in every app. Écrire le code de votre propre convertisseur de texte en type est fastidieux et sujet à erreur.Writing your own text to type converter code is tedious, and error prone.

Fonctionnement de la liaison de modèleHow model binding works

Quand MVC reçoit une requête HTTP, il la route vers une méthode d’action spécifique d’un contrôleur.When MVC receives an HTTP request, it routes it to a specific action method of a controller. Il détermine la méthode d’action à exécuter en fonction de ce qui se trouve dans les données de la route, puis il lie les valeurs de la requête HTTP aux paramètres de cette méthode d’action.It determines which action method to run based on what is in the route data, then it binds values from the HTTP request to that action method's parameters. Considérez par exemple l’URL suivante :For example, consider the following URL:

http://contoso.com/movies/edit/2

Le modèle de route se présentant comme ceci, {controller=Home}/{action=Index}/{id?}, movies/edit/2 route vers le contrôleur Movies et sa méthode d’action Edit.Since the route template looks like this, {controller=Home}/{action=Index}/{id?}, movies/edit/2 routes to the Movies controller, and its Edit action method. Il accepte également un paramètre facultatif nommé id.It also accepts an optional parameter called id. Le code de la méthode d’action doit ressembler à ceci :The code for the action method should look something like this:

public IActionResult Edit(int? id)

Remarque : Les chaînes dans la route de l’URL ne respectent pas la casse.Note: The strings in the URL route are not case sensitive.

MVC tente de lier les données de la requête aux paramètres de l’action avec le nom.MVC will try to bind request data to the action parameters by name. MVC recherche des valeurs pour chaque paramètre en utilisant le nom du paramètre et les noms de ses propriétés définissables publiques.MVC will look for values for each parameter using the parameter name and the names of its public settable properties. Dans l’exemple ci-dessus, le seul paramètre d’action est nommé id, que MVC lie à la valeur portant le même nom dans les valeurs de la route.In the above example, the only action parameter is named id, which MVC binds to the value with the same name in the route values. En plus des valeurs de la route, MVC lie les données des différentes parties de la requête, ceci selon un ordre défini.In addition to route values MVC will bind data from various parts of the request and it does so in a set order. Voici une liste des sources de données dans l’ordre où la liaison de modèle les recherche :Below is a list of the data sources in the order that model binding looks through them:

  1. Form values : il s’agit de valeurs de formulaire qui vont dans la requête HTTP avec la méthode POST.Form values: These are form values that go in the HTTP request using the POST method. (notamment les requêtes POST jQuery).(including jQuery POST requests).

  2. Route values : l’ensemble des valeurs de la route fournies par le routageRoute values: The set of route values provided by Routing

  3. Query strings : la partie de chaîne de la requête de l’URI.Query strings: The query string part of the URI.

Remarque : Les valeurs de formulaire, les données des routes et les chaînes de requête sont toutes stockées sous la forme de paires nom-valeur.Note: Form values, route data, and query strings are all stored as name-value pairs.

Comme la liaison de modèle a demandé une clé nommée id et qu’aucun élément n’est nommé id dans les valeurs de formulaire, il est passé aux valeurs de la route pour rechercher cette clé.Since model binding asked for a key named id and there's nothing named id in the form values, it moved on to the route values looking for that key. Dans notre exemple, il trouve une correspondance.In our example, it's a match. La liaison est effectuée et la valeur est convertie un entier dont la valeur est 2.Binding happens, and the value is converted to the integer 2. La même requête qui utiliserait Edit(string id) convertirait en une chaîne « 2 ».The same request using Edit(string id) would convert to the string "2".

Jusqu’à présent, l’exemple utilise des types simples.So far the example uses simple types. Dans MVC, les types simples sont tous les types primitifs .NET ou les types avec un convertisseur de type chaîne.In MVC simple types are any .NET primitive type or type with a string type converter. Si le paramètre de la méthode d’action était une classe comme le type Movie, qui contient à la fois des types simples et des comme complexes comme propriétés, la liaison de modèle de MVC pourrait le gérer correctement.If the action method's parameter were a class such as the Movie type, which contains both simple and complex types as properties, MVC's model binding will still handle it nicely. Il utilise la réflexion et la récursivité pour parcourir les propriétés des types complexes en recherchant des correspondances.It uses reflection and recursion to traverse the properties of complex types looking for matches. La liaison de modèle recherche le modèle nom_paramètre.nom_propriété pour lier des valeurs aux propriétés.Model binding looks for the pattern parameter_name.property_name to bind values to properties. S’il ne trouve pas de valeurs correspondantes de ce formulaire, il tente de lier en utilisant seulement le nom de propriété.If it doesn't find matching values of this form, it will attempt to bind using just the property name. Pour des types comme Collection, la liaison de modèle recherche des correspondances avec nom_paramètre[index] ou simplement avec [index].For those types such as Collection types, model binding looks for matches to parameter_name[index] or just [index]. La liaison de modèle traite les types Dictionary de la même façon, en demandant nom_paramètre[clé] ou simplement [clé], à condition que les clés soient des types simples.Model binding treats Dictionary types similarly, asking for parameter_name[key] or just [key], as long as the keys are simple types. Les clés qui sont prises en charge correspondent aux noms de champ HTML et aux helpers de balise générés pour le même type de modèle.Keys that are supported match the field names HTML and tag helpers generated for the same model type. Ceci permet l’aller-retour des valeurs, de sorte que les champs de formulaire restent remplis avec l’entrée de l’utilisateur pour lui faciliter la tâche, par exemple quand les données liées à partir d’une création ou d’une modification n’ont pas été validées.This enables round-tripping values so that the form fields remain filled with the user's input for their convenience, for example, when bound data from a create or edit didn't pass validation.

Pour que la liaison puisse se faire, la classe doit avoir un constructeur public par défaut et le membre à lier doit être constitué de propriétés publiques accessibles en écriture.In order for binding to happen the class must have a public default constructor and member to be bound must be public writable properties. Quand la liaison de modèle se produit, la classe est seulement instanciée avec le constructeur public par défaut, puis les propriétés peuvent être définies.When model binding happens the class will only be instantiated using the public default constructor, then the properties can be set.

Quand un paramètre est lié, la liaison de modèle cesse de rechercher des valeurs avec ce nom et elle passe à la liaison du paramètre suivant.When a parameter is bound, model binding stops looking for values with that name and it moves on to bind the next parameter. Sinon, le comportement de la liaison de modèle par défaut définit les paramètres à leurs valeurs par défaut en fonction de leur type :Otherwise, the default model binding behavior sets parameters to their default values depending on their type:

  • T[] : À l’exception des tableaux de type byte[], la liaison définit les paramètres de type T[] sur Array.Empty<T>().T[]: With the exception of arrays of type byte[], binding sets parameters of type T[] to Array.Empty<T>(). Les tableaux de type byte[] ont la valeur null.Arrays of type byte[] are set to null.

  • Types de référence : la liaison crée une instance d’une classe avec le constructeur par défaut sans définir des propriétés.Reference Types: Binding creates an instance of a class with the default constructor without setting properties. Cependant, la liaison de modèle définit les string sur null.However, model binding sets string parameters to null.

  • Types Nullable : les types Nullable sont définis sur null.Nullable Types: Nullable types are set to null. Dans l’exemple ci-dessus, la liaison de modèle définit id sur null, car il est de type int?.In the above example, model binding sets id to null since it's of type int?.

  • Types de valeur : les types de valeur non-Nullable de type T sont définis sur default(T).Value Types: Non-nullable value types of type T are set to default(T). Par exemple, la liaison de modèle définit un paramètre int id sur 0.For example, model binding will set a parameter int id to 0. Envisagez d’utiliser la validation de modèle ou des types Nullables au lieu de travailler avec les valeurs par défaut.Consider using model validation or nullable types rather than relying on default values.

Si la liaison échoue, MVC ne génère pas d’erreur.If binding fails, MVC doesn't throw an error. Chaque action acceptant une entrée utilisateur doit vérifier la propriété ModelState.IsValid.Every action which accepts user input should check the ModelState.IsValid property.

Remarque : Chaque entrée dans la propriété ModelState du contrôleur est une ModelStateEntry contenant une propriété Errors.Note: Each entry in the controller's ModelState property is a ModelStateEntry containing an Errors property. Il est rarement nécessaire interroger cette collection vous-même.It's rarely necessary to query this collection yourself. Utilisez plutôt ModelState.IsValid.Use ModelState.IsValid instead.

En outre, MVC doit prendre en compte certains types de données spéciaux lors de la liaison de modèle :Additionally, there are some special data types that MVC must consider when performing model binding:

  • IFormFile, IEnumerable<IFormFile> : un ou plusieurs fichiers chargés qui font partie de la requête HTTP.IFormFile, IEnumerable<IFormFile>: One or more uploaded files that are part of the HTTP request.

  • CancellationToken : utilisé pour annuler l’activité dans les contrôleurs asynchrones.CancellationToken: Used to cancel activity in asynchronous controllers.

Ces types peuvent être liés à des paramètres d’action ou à des propriétés sur un type de classe.These types can be bound to action parameters or to properties on a class type.

Une fois que la liaison de modèle est terminée, la validation se produit.Once model binding is complete, Validation occurs. La liaison de modèle par défaut fonctionne bien pour la grande majorité des scénarios de développement.Default model binding works great for the vast majority of development scenarios. Elle est également extensible : si vous avez des besoins spécifiques, vous pouvez donc personnaliser le comportement intégré.It's also extensible so if you have unique needs you can customize the built-in behavior.

Personnaliser le comportement de la liaison de modèle avec des attributsCustomize model binding behavior with attributes

MVC contient plusieurs attributs que vous pouvez utiliser pour spécifier son comportement de liaison de modèle par défaut vers une autre source.MVC contains several attributes that you can use to direct its default model binding behavior to a different source. Par exemple, vous pouvez spécifier si la liaison est obligatoire pour une propriété, ou si elle ne doit jamais se produire, avec les attributs [BindRequired] ou [BindNever].For example, you can specify whether binding is required for a property, or if it should never happen at all by using the [BindRequired] or [BindNever] attributes. Vous pouvez aussi remplacer la source de données par défaut et spécifier la source de données du classeur de modèles.Alternatively, you can override the default data source, and specify the model binder's data source. Voici une liste des attributs de liaison de modèle :Below is a list of model binding attributes:

  • [BindRequired] : cet attribut ajoute une erreur d’état de modèle si la liaison ne peut pas se produire.[BindRequired]: This attribute adds a model state error if binding cannot occur.

  • [BindNever] : indique au classeur de modèles de ne jamais lier à ce paramètre.[BindNever]: Tells the model binder to never bind to this parameter.

  • [FromHeader], [FromQuery], [FromRoute], [FromForm] : utilisez ces attributs pour spécifier la source de liaison exacte que vous voulez appliquer.[FromHeader], [FromQuery], [FromRoute], [FromForm]: Use these to specify the exact binding source you want to apply.

  • [FromServices] : cet attribut utilise l’injection de dépendances pour lier des paramètres de services.[FromServices]: This attribute uses dependency injection to bind parameters from services.

  • [FromBody] : utilisez les formateurs configurés pour lier des données du corps de la requête.[FromBody]: Use the configured formatters to bind data from the request body. Le formateur est sélectionné en fonction du type de contenu de la requête.The formatter is selected based on content type of the request.

  • [ModelBinder] : utilisé pour remplacer le classeur de modèles, la source de liaison et le nom par défaut.[ModelBinder]: Used to override the default model binder, binding source and name.

Les attributs sont très utiles quand vous devez remplacer le comportement par défaut de la liaison de modèle.Attributes are very helpful tools when you need to override the default behavior of model binding.

Lier des données mises en forme du corps de la requêteBind formatted data from the request body

Les données des requêtes peuvent exister dans différents formats, notamment JSON, XML et beaucoup d’autres.Request data can come in a variety of formats including JSON, XML and many others. Quand vous utilisez l’attribut [FromBody] pour indiquer que vous voulez lier un paramètre à des données du corps de la requête, MVC utilise un ensemble de formateurs configuré pour gérer les données de la requête en fonction du type de contenu.When you use the [FromBody] attribute to indicate that you want to bind a parameter to data in the request body, MVC uses a configured set of formatters to handle the request data based on its content type. Par défaut, MVC inclut une classe JsonInputFormatter pour la gestion des données JSON, mais vous pouvez ajouter des formateurs supplémentaires pour la gestion du format XML et d’autres formats personnalisés.By default MVC includes a JsonInputFormatter class for handling JSON data, but you can add additional formatters for handling XML and other custom formats.

Note

Il peut y avoir au plus un paramètre par action décorée avec [FromBody].There can be at most one parameter per action decorated with [FromBody]. Le runtime d’ASP.NET Core MVC délègue la responsabilité de lire le flux de la requête au formateur.The ASP.NET Core MVC run-time delegates the responsibility of reading the request stream to the formatter. Une fois que le flux de la requête est lu pour un paramètre, il n’est généralement pas possible de relire le flux de la requête pour lier d’autres paramètres [FromBody].Once the request stream is read for a parameter, it's generally not possible to read the request stream again for binding other [FromBody] parameters.

Note

JsonInputFormatter est le formateur par défaut et est basé sur Json.NET.The JsonInputFormatter is the default formatter and is based on Json.NET.

ASP.NET sélectionne les formateurs d’entrée en fonction de l’en-tête Content-Type et du type de paramètre, sauf si un attribut lui est appliqué qui spécifie un autre formateur.ASP.NET selects input formatters based on the Content-Type header and the type of the parameter, unless there's an attribute applied to it specifying otherwise. Si vous voulez utiliser XML ou un autre format, vous devez le configurer dans le fichier Startup.cs, mais il peut être nécessaire d’obtenir d’abord une référence à Microsoft.AspNetCore.Mvc.Formatters.Xml en utilisant NuGet.If you'd like to use XML or another format you must configure it in the Startup.cs file, but you may first have to obtain a reference to Microsoft.AspNetCore.Mvc.Formatters.Xml using NuGet. Votre code de démarrage doit ressembler à ceci :Your startup code should look something like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddXmlSerializerFormatters();
   }

Le code du fichier Startup.cscontient une méthode ConfigureServices avec un argument services, que vous pouvez utiliser pour créer des services pour votre application ASP.NET.Code in the Startup.cs file contains a ConfigureServices method with a services argument you can use to build up services for your ASP.NET app. Dans l’exemple, nous ajoutons un formateur XML en tant que service, que MVC fournira pour cette application.In the sample, we are adding an XML formatter as a service that MVC will provide for this app. L’argument options passé dans la méthode AddMvc vous permet d’ajouter et de gérer des filtres, des formateurs et d’autres options du système depuis MVC dès le démarrage de l’application.The options argument passed into the AddMvc method allows you to add and manage filters, formatters, and other system options from MVC upon app startup. Appliquez ensuite l’attribut Consumes aux classes de contrôleur ou aux méthodes d’action pour travailler avec le format souhaité.Then apply the Consumes attribute to controller classes or action methods to work with the format you want.

Liaison de modèle personnaliséeCustom Model Binding

Vous pouvez étendre la liaison de modèle en écrivant vos propres classeurs de modèles personnalisés.You can extend model binding by writing your own custom model binders. Découvrez plus d’informations sur la liaison de modèle personnalisée.Learn more about custom model binding.