asp.net-web-api
OData avec l'API Web Asp.net
Recherche…
Installer les packages OData
Dans le menu Outils, sélectionnez NuGet Package Manager> Console du gestionnaire de packages. Dans la fenêtre Console du Gestionnaire de packages, tapez:
Install-Package Microsoft.AspNet.Odata
Cette commande installe les derniers packages OData NuGet.
Activer le cadre d'entité
Pour ce tutoriel, nous utiliserons le code Entity Framework (EF) First pour créer la base de données principale.
API Web OData ne nécessite pas EF. Utilisez toute couche d'accès aux données capable de traduire des entités de base de données en modèles.
Tout d'abord, installez le package NuGet pour EF. Dans le menu Outils , sélectionnez NuGet Package Manager > Console du gestionnaire de packages . Dans la fenêtre Console du Gestionnaire de packages, tapez:
Install-Package EntityFramework
Ouvrez le fichier Web.config et ajoutez la section suivante dans l'élément de configuration , après l'élément configSections .
<configuration>
<configSections>
<!-- ... -->
</configSections>
<!-- Add this: -->
<connectionStrings>
<add name="ProductsContext" connectionString="Data Source=(localdb)\v11.0;
Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True;
AttachDbFilename=|DataDirectory|ProductsContext.mdf"
providerName="System.Data.SqlClient" />
</connectionStrings>
Ce paramètre ajoute une chaîne de connexion pour une base de données LocalDB. Cette base de données sera utilisée lorsque vous exécuterez l'application localement.
Ensuite, ajoutez une classe nommée ProductsContext au dossier Models:
using System.Data.Entity;
namespace ProductService.Models
{
public class ProductsContext : DbContext
{
public ProductsContext()
: base("name=ProductsContext")
{
}
public DbSet<Product> Products { get; set; }
}
}
Dans le constructeur, "name = ProductsContext" donne le nom de la chaîne de connexion.
Configurez le point de terminaison OData
Ouvrez le fichier App_Start / WebApiConfig.cs. Ajoutez les instructions suivantes en utilisant :
using ProductService.Models;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
Ajoutez ensuite le code suivant à la méthode Register :
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// New code:
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel());
}
}
Ce code fait deux choses:
- Crée un modèle de données d'entité (EDM).
- Ajoute un itinéraire.
Un EDM est un modèle abstrait des données. L'EDM est utilisé pour créer le document de métadonnées du service. La classe ODataConventionModelBuilder crée un modèle EDM en utilisant des conventions de dénomination par défaut. Cette approche nécessite le moins de code. Si vous souhaitez davantage de contrôle sur l'EDM, vous pouvez utiliser la classe ODataModelBuilder pour créer l'EDM en ajoutant explicitement des propriétés, des clés et des propriétés de navigation.
Une route indique à Web API comment acheminer les requêtes HTTP vers le noeud final. Pour créer un itinéraire OData v4, appelez la méthode d'extension MapODataServiceRoute .
Si votre application possède plusieurs points de terminaison OData, créez un itinéraire distinct pour chacun. Attribuez à chaque itinéraire un nom et un préfixe d'itinéraire uniques.
Ajouter le contrôleur OData
Un contrôleur est une classe qui gère les requêtes HTTP. Vous créez un contrôleur distinct pour chaque ensemble d'entités dans votre service OData. Dans ce tutoriel, vous créerez un contrôleur pour l’entité Produit.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le dossier Contrôleurs et sélectionnez Ajouter > Classe . Nommez la classe ProductsController.
La version de ce didacticiel pour OData v3 utilise l'échafaudage Add Controller. Actuellement, il n'y a pas d'échafaudage pour OData v4.
Remplacez le code passe-partout dans ProductsController.cs par le suivant.
using ProductService.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.OData;
namespace ProductService.Controllers
{
public class ProductsController : ODataController
{
ProductsContext db = new ProductsContext();
private bool ProductExists(int key)
{
return db.Products.Any(p => p.Id == key);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
Le contrôleur utilise la classe ProductsContext pour accéder à la base de données à l'aide d'EF. Notez que le contrôleur remplace la méthode Dispose pour se débarrasser de ProductsContext .
C'est le point de départ du contrôleur. Ensuite, nous allons ajouter des méthodes pour toutes les opérations CRUD.
Exécution de CRUD sur l'ensemble d'entités
Interrogation de l'ensemble d'entités
Ajoutez les méthodes suivantes à ProductsController .
[EnableQuery]
public IQueryable<Product> Get()
{
return db.Products;
}
[EnableQuery]
public SingleResult<Product> Get([FromODataUri] int key)
{
IQueryable<Product> result = db.Products.Where(p => p.Id == key);
return SingleResult.Create(result);
}
La version sans paramètre de la méthode Get renvoie la collection entière de produits. La méthode Get avec un paramètre key recherche un produit par sa clé (dans ce cas, la propriété Id).
L'attribut [EnableQuery] permet aux clients de modifier la requête en utilisant des options de requête telles que $ filter, $ sort et $ page. Pour plus d'informations, voir Prise en charge des options de requête OData .
Ajout d'une entité à l'ensemble d'entités
Pour permettre aux clients d'ajouter un nouveau produit à la base de données, ajoutez la méthode suivante à ProductsController .
public async Task<IHttpActionResult> Post(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Products.Add(product);
await db.SaveChangesAsync();
return Created(product);
}
Mise à jour d'une entité
OData prend en charge deux sémantiques différentes pour mettre à jour une entité, PATCH et PUT.
- PATCH effectue une mise à jour partielle. Le client spécifie uniquement les propriétés à mettre à jour.
- PUT remplace l'entité entière.
L'inconvénient de PUT est que le client doit envoyer des valeurs pour toutes les propriétés de l'entité, y compris celles qui ne changent pas. La spécification OData indique que PATCH est préféré.
En tout cas, voici le code pour les méthodes PATCH et PUT:
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var entity = await db.Products.FindAsync(key);
if (entity == null)
{
return NotFound();
}
product.Patch(entity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(entity);
}
public async Task<IHttpActionResult> Put([FromODataUri] int key, Product update)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (key != update.Id)
{
return BadRequest();
}
db.Entry(update).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(update);
}
Dans le cas de PATCH, le contrôleur utilise le type Delta <T> pour suivre les modifications.
Supprimer une entité
Pour permettre aux clients de supprimer un produit de la base de données, ajoutez la méthode suivante à ProductsController .
public async Task<IHttpActionResult> Delete([FromODataUri] int key)
{
var product = await db.Products.FindAsync(key);
if (product == null)
{
return NotFound();
}
db.Products.Remove(product);
await db.SaveChangesAsync();
return StatusCode(HttpStatusCode.NoContent);
}