asp.net-web-api
OData met Asp.net Web API
Zoeken…
Installeer de OData-pakketten
Selecteer NuGet Pakketbeheer> Pakketbeheerconsole in het menu Extra. Typ in het venster Pakketbeheerconsole:
Install-Package Microsoft.AspNet.Odata
Met deze opdracht worden de nieuwste OData NuGet-pakketten geïnstalleerd.
Entiteitskader inschakelen
Voor deze zelfstudie gebruiken we Entity Framework (EF) Code First om de back-enddatabase te maken.
Web API OData vereist geen EF. Gebruik een gegevenstoegangslaag die database-entiteiten kan vertalen in modellen.
Installeer eerst het NuGet-pakket voor EF. Selecteer NuGet Pakketbeheer > Pakketbeheerconsole in het menu Extra . Typ in het venster Pakketbeheerconsole:
Install-Package EntityFramework
Open het bestand Web.config en voeg de volgende sectie in het configuratie- element toe, na het configSections- element.
<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>
Deze instelling voegt een verbindingsreeks toe voor een LocalDB-database. Deze database wordt gebruikt wanneer u de app lokaal uitvoert.
Voeg vervolgens een klasse met de naam ProductsContext toe aan de map Modellen:
using System.Data.Entity;
namespace ProductService.Models
{
public class ProductsContext : DbContext
{
public ProductsContext()
: base("name=ProductsContext")
{
}
public DbSet<Product> Products { get; set; }
}
}
In de constructor geeft "name = ProductsContext" de naam van de verbindingsreeks.
Configureer het OData-eindpunt
Open het bestand App_Start / WebApiConfig.cs. Voeg het volgende toe met behulp van instructies:
using ProductService.Models;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
Voeg vervolgens de volgende code toe aan de methode 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());
}
}
Deze code doet twee dingen:
- Creëert een Entity Data Model (EDM).
- Voegt een route toe.
Een EDM is een abstract model van de gegevens. De EDM wordt gebruikt om het metadatadocument van de service te maken. De klasse ODataConventionModelBuilder maakt een EDM met standaard naamgevingsconventies. Deze aanpak vereist de minste code. Als u meer controle over de EDM wilt, kunt u de klasse ODataModelBuilder gebruiken om de EDM te maken door expliciet eigenschappen, sleutels en navigatie-eigenschappen toe te voegen.
Een route vertelt Web API hoe HTTP-aanvragen naar het eindpunt moeten worden gerouteerd. Als u een OData v4-route wilt maken, roept u de uitbreidingsmethode MapODataServiceRoute aan .
Als uw toepassing meerdere OData-eindpunten heeft, maakt u voor elk een afzonderlijke route. Geef elke route een unieke routenaam en voorvoegsel.
Voeg de OData-controller toe
Een controller is een klasse die HTTP-aanvragen verwerkt. U maakt een afzonderlijke controller voor elke entiteitset in uw OData-service. In deze zelfstudie maakt u één controller voor de productentiteit.
Klik in Solution Explorer met de rechtermuisknop op de map Controllers en selecteer Toevoegen > Klasse . Noem de klasse ProductsController.
De versie van deze zelfstudie voor OData v3 maakt gebruik van de steiger Controller toevoegen. Momenteel is er geen steiger voor OData v4.
Vervang de boilerplate-code in ProductsController.cs door het volgende.
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);
}
}
}
De controller gebruikt de klasse ProductsContext voor toegang tot de database met EF. Merk op dat de controller de Dispose- methode overschrijft om de ProductsContext te verwijderen.
Dit is het startpunt voor de controller. Vervolgens voegen we methoden toe voor alle CRUD-bewerkingen.
CRUD uitvoeren op de entiteitset
De entiteitenset opvragen
Voeg de volgende methoden toe aan 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);
}
De parameterloze versie van de methode Get retourneert de volledige Products-collectie. De methode Get met een sleutelparameter zoekt een product op sleutel (in dit geval de eigenschap Id).
Met het kenmerk [EnableQuery] kunnen clients de query wijzigen met behulp van queryopties zoals $ filter, $ sort en $ page. Zie Ondersteuning van OData-queryopties voor meer informatie.
Een entiteit toevoegen aan de entiteitset
Om clients in staat te stellen een nieuw product aan de database toe te voegen, voegt u de volgende methode toe aan ProductsController .
public async Task<IHttpActionResult> Post(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Products.Add(product);
await db.SaveChangesAsync();
return Created(product);
}
Een entiteit bijwerken
OData ondersteunt twee verschillende semantiek voor het bijwerken van een entiteit, PATCH en PUT.
- PATCH voert een gedeeltelijke update uit. De client geeft alleen de eigenschappen op die moeten worden bijgewerkt.
- PUT vervangt de gehele entiteit.
Het nadeel van PUT is dat de client waarden moet verzenden voor alle eigenschappen in de entiteit, inclusief waarden die niet veranderen. De OData-specificatie geeft aan dat PATCH de voorkeur heeft.
In elk geval is hier de code voor zowel PATCH- als PUT-methoden:
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);
}
In het geval van PATCH gebruikt de controller het type Delta <T> om de wijzigingen te volgen.
Een entiteit verwijderen
Om clients in staat te stellen een product uit de database te verwijderen, voegt u de volgende methode toe aan 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);
}