Creare un Endpoint OData v4 tramite l'API Web ASP.NETCreate an OData v4 Endpoint Using ASP.NET Web API

Open Data Protocol (OData) è un protocollo di accesso di dati per il web.The Open Data Protocol (OData) is a data access protocol for the web. OData offre un metodo uniforme per eseguire query e modificare set di dati tramite operazioni CRUD (creare, leggere, aggiornare ed eliminare).OData provides a uniform way to query and manipulate data sets through CRUD operations (create, read, update, and delete).

API Web ASP.NET supporta v3 e v4 del protocollo.ASP.NET Web API supports both v3 and v4 of the protocol. È anche possibile avere un endpoint v4 che viene eseguito side-by-side con un endpoint di v3.You can even have a v4 endpoint that runs side-by-side with a v3 endpoint.

Questa esercitazione illustra come creare un endpoint OData v4 che supporta operazioni CRUD.This tutorial shows how to create an OData v4 endpoint that supports CRUD operations.

Versioni del software utilizzate nell'esercitazioneSoftware versions used in the tutorial

  • Web API 5.2Web API 5.2
  • OData v4OData v4
  • Visual Studio 2017 (download di Visual Studio 2017 qui)Visual Studio 2017 (download Visual Studio 2017 here)
  • Entity Framework 6Entity Framework 6
  • .NET 4.7.2.NET 4.7.2

Versioni dell'esercitazioneTutorial versions

Per OData versione 3, vedere creazione di un Endpoint OData v3.For the OData Version 3, see Creating an OData v3 Endpoint.

Creare il progetto di Visual StudioCreate the Visual Studio Project

In Visual Studio, dai File dal menu New > progetto.In Visual Studio, from the File menu, select New > Project.

Espandere Installed > Visual C# > Webe selezionare il applicazione Web ASP.NET (.NET Framework) modello.Expand Installed > Visual C# > Web, and select the ASP.NET Web Application (.NET Framework) template. Denominare il progetto "ProductService".Name the project "ProductService".

Scegliere OK.Select OK.

Selezionare il vuoto modello.Select the Empty template. Sotto aggiungere le cartelle e di base di riferimenti per:, selezionare API Web.Under Add folders and core references for:, select Web API. Scegliere OK.Select OK.

Installare i pacchetti di ODataInstall the OData packages

Dal menu Strumenti selezionare Gestione pacchetti NuGet > Console di Gestione pacchetti.From the Tools menu, select NuGet Package Manager > Package Manager Console. Nella finestra della Console di gestione pacchetti, digitare:In the Package Manager Console window, type:

Install-Package Microsoft.AspNet.Odata

Questo comando consente di installare gli ultimi pacchetti NuGet di OData.This command installs the latest OData NuGet packages.

Aggiungere una classe del modelloAdd a model class

Oggetto modello è un oggetto che rappresenta un'entità di dati nell'applicazione.A model is an object that represents a data entity in your application.

In Esplora soluzioni fare clic sulla cartella Models.In Solution Explorer, right-click the Models folder. Dal menu di scelta rapida, selezionare Add > classe.From the context menu, select Add > Class.

Note

Per convenzione, le classi del modello vengono inserite nella cartella Models, ma non è necessario seguono questa convenzione nei propri progetti.By convention, model classes are placed in the Models folder, but you don't have to follow this convention in your own projects.

Assegnare alla classe il nome Product.Name the class Product. Nel file Product.cs, sostituire il codice boilerplate con gli elementi seguenti:In the Product.cs file, replace the boilerplate code with the following:

namespace ProductService.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }
}

Il Id proprietà è la chiave di entità.The Id property is the entity key. I client possono eseguire query sulle entità tramite chiave.Clients can query entities by key. Per ottenere il prodotto con ID 5, ad esempio, l'URI è /Products(5).For example, to get the product with ID of 5, the URI is /Products(5). Il Id proprietà sarà anche la chiave primaria nel database di back-end.The Id property will also be the primary key in the back-end database.

Abilitare Entity FrameworkEnable Entity Framework

Per questa esercitazione, useremo Code First di Entity Framework (EF) per creare il database back-end.For this tutorial, we'll use Entity Framework (EF) Code First to create the back-end database.

Note

API Web OData non richiede Entity Framework.Web API OData does not require EF. Usare qualsiasi livello di accesso ai dati che può tradurre le entità di database in modelli.Use any data-access layer that can translate database entities into models.

Prima di tutto installare il pacchetto NuGet per Entity Framework.First, install the NuGet package for EF. Dal menu Strumenti selezionare Gestione pacchetti NuGet > Console di Gestione pacchetti.From the Tools menu, select NuGet Package Manager > Package Manager Console. Nella finestra della Console di gestione pacchetti, digitare:In the Package Manager Console window, type:

Install-Package EntityFramework

Aprire il file Web. config e aggiungere la sezione seguente all'interno di configuration elemento, dopo il configSections elemento.Open the Web.config file, and add the following section inside the configuration element, after the configSections element.

<configuration>
  <configSections>
    <!-- ... -->
  </configSections>

  <!-- Add this: -->
  <connectionStrings>
    <add name="ProductsContext" connectionString="Data Source=(localdb)\mssqllocaldb; 
        Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True; 
        AttachDbFilename=|DataDirectory|ProductsContext.mdf"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

Questa impostazione consente di aggiungere una stringa di connessione per un database LocalDB.This setting adds a connection string for a LocalDB database. Questo database verrà utilizzato quando si esegue l'app in locale.This database will be used when you run the app locally.

Successivamente, aggiungere una classe denominata ProductsContext nella cartella Models:Next, add a class named ProductsContext to the Models folder:

using System.Data.Entity;
namespace ProductService.Models
{
    public class ProductsContext : DbContext
    {
        public ProductsContext() 
                : base("name=ProductsContext")
        {
        }
        public DbSet<Product> Products { get; set; }
    }
}

Nel costruttore, "name=ProductsContext" fornisce il nome della stringa di connessione.In the constructor, "name=ProductsContext" gives the name of the connection string.

Configurare l'endpoint ODataConfigure the OData endpoint

Aprire il file App_Start/WebApiConfig.cs.Open the file App_Start/WebApiConfig.cs. Aggiungere il codice seguente usando istruzioni:Add the following using statements:

using ProductService.Models;
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNet.OData.Extensions;

Quindi aggiungere il codice seguente per il registrare metodo:Then add the following code to the Register method:

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());
    }
}

Questo codice esegue due operazioni:This code does two things:

  • Crea un Entity Data Model (EDM).Creates an Entity Data Model (EDM).
  • Aggiunge una route.Adds a route.

Un modello EDM è un modello di dati astratto.An EDM is an abstract model of the data. EDM viene utilizzato per creare il documento di metadati di servizio.The EDM is used to create the service metadata document. Il ODataConventionModelBuilder classe crea un modello EDM utilizzando le convenzioni di denominazione predefinito.The ODataConventionModelBuilder class creates an EDM by using default naming conventions. Questo approccio richiede il minor quantità di codice.This approach requires the least code. Se si desidera maggiore controllo sul modello EDM, è possibile usare la ODataModelBuilder classe per creare il modello EDM mediante l'aggiunta di proprietà, le chiavi e le proprietà di navigazione in modo esplicito.If you want more control over the EDM, you can use the ODataModelBuilder class to create the EDM by adding properties, keys, and navigation properties explicitly.

Oggetto route indica come indirizzare le richieste HTTP all'endpoint API Web.A route tells Web API how to route HTTP requests to the endpoint. Per creare una route di OData v4, chiamare il MapODataServiceRoute metodo di estensione.To create an OData v4 route, call the MapODataServiceRoute extension method.

Se l'applicazione dispone di più endpoint OData, creare una route separata per ognuna.If your application has multiple OData endpoints, create a separate route for each. Assegnare ogni route un nome di route univoco e un prefisso.Give each route a unique route name and prefix.

Aggiungere il controller ODataAdd the OData controller

Oggetto controller è una classe che gestisce le richieste HTTP.A controller is a class that handles HTTP requests. Creare un controller separato per ogni set di entità nel servizio OData.You create a separate controller for each entity set in your OData service. In questa esercitazione si creerà un controller, per il Product entità.In this tutorial, you will create one controller, for the Product entity.

In Esplora soluzioni fare doppio clic su cartella controller e selezionare Add > classe.In Solution Explorer, right-click the Controllers folder and select Add > Class. Assegnare alla classe il nome ProductsController.Name the class ProductsController.

Note

La versione di questa esercitazione per OData v3 usi il Aggiungi Controller scaffolding.The version of this tutorial for OData v3 uses the Add Controller scaffolding. Attualmente, non è nessuna scaffolding per OData v4.Currently, there is no scaffolding for OData v4.

Sostituire il codice boilerplate in ProductsController.cs con il codice seguente.Replace the boilerplate code in ProductsController.cs with the following.

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);
        }
    }
}

Il controller viene utilizzato il ProductsContext classe per accedere al database tramite Entity Framework.The controller uses the ProductsContext class to access the database using EF. Si noti che il controller esegue l'override di Dispose metodo per eliminare le ProductsContext.Notice that the controller overrides the Dispose method to dispose of the ProductsContext.

Questo è il punto di partenza per il controller.This is the starting point for the controller. Successivamente, si aggiungerà metodi per tutte le operazioni CRUD.Next, we'll add methods for all of the CRUD operations.

Eseguire una query del set di entitàQuery the entity set

Aggiungere i metodi seguenti alla ProductsController.Add the following methods to 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 versione senza parametri del Get metodo restituisce l'intera raccolta di prodotti.The parameterless version of the Get method returns the entire Products collection. Il Get metodo con un chiave parametro Cerca un prodotto in base alla chiave (in questo caso, il Id proprietà).The Get method with a key parameter looks up a product by its key (in this case, the Id property).

Il [EnableQuery] attributo consente ai client di modificare la query, usando le opzioni di query, ad esempio $filter $sort e $page.The [EnableQuery] attribute enables clients to modify the query, by using query options such as $filter, $sort, and $page. Per altre informazioni, vedere che supportano le opzioni di Query OData.For more information, see Supporting OData Query Options.

Aggiungere un'entità per il set di entitàAdd an entity to the entity set

Per consentire ai client di aggiungere un nuovo prodotto per il database, aggiungere il metodo seguente alla ProductsController.To enable clients to add a new product to the database, add the following method to ProductsController.

public async Task<IHttpActionResult> Post(Product product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    db.Products.Add(product);
    await db.SaveChangesAsync();
    return Created(product);
}

Aggiornare un'entitàUpdate an entity

OData supporta due diverse semantiche per aggiornare un'entità, PATCH e PUT.OData supports two different semantics for updating an entity, PATCH and PUT.

  • PATCH esegue un aggiornamento parziale.PATCH performs a partial update. Il client specifica solo le proprietà da aggiornare.The client specifies just the properties to update.
  • PUT sostituisce l'intera entità.PUT replaces the entire entity.

Lo svantaggio di PUT è che il client deve inviare i valori per tutte le proprietà dell'entità, inclusi i valori che non vengano modificate.The disadvantage of PUT is that the client must send values for all of the properties in the entity, including values that are not changing. Il specifica OData dichiara che PATCH è preferita.The OData spec states that PATCH is preferred.

In ogni caso, ecco il codice per i metodi sia PATCH e PUT:In any case, here is the code for both PATCH and PUT methods:

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);
}

Nel caso di PATCH, il controller Usa il Delta<T> tipo per tenere traccia delle modifiche.In the case of PATCH, the controller uses the Delta<T> type to track the changes.

Eliminare un'entitàDelete an entity

Per abilitare i client eliminare un prodotto dal database, aggiungere il metodo seguente alla ProductsController.To enable clients to delete a product from the database, add the following method to 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);
}