Esercitazione: creare un'API Web con ASP.NET CoreTutorial: Create a web API with ASP.NET Core

Di Rick Anderson e Mike WassonBy Rick Anderson and Mike Wasson

Questa esercitazione illustra le nozioni di base della creazione di un'API Web con ASP.NET Core.This tutorial teaches the basics of building a web API with ASP.NET Core.

In questa esercitazione si imparerà a:In this tutorial, you learn how to:

  • Creare un progetto di API Web.Create a web API project.
  • Aggiungere una classe modello e un contesto di database.Add a model class and a database context.
  • Eseguire lo scaffolding di un controller con i metodi CRUD.Scaffold a controller with CRUD methods.
  • Configurare il routing, i percorsi URL e i valori restituiti.Configure routing, URL paths, and return values.
  • Chiamare l'API Web con Postman.Call the web API with Postman.

Al termine si avrà un'API Web che può gestire gli elementi di tipo "attività" archiviati in un database.At the end, you have a web API that can manage "to-do" items stored in a database.

Panoramica diOverview

Questa esercitazione consente di creare l'API seguente:This tutorial creates the following API:

APIAPI DescrizioneDescription Testo della richiestaRequest body Corpo della rispostaResponse body
GET /api/TodoItemsGET /api/TodoItems Ottiene tutti gli elementi attivitàGet all to-do items nessunaNone Matrice di elementi attivitàArray of to-do items
GET /api/TodoItems/{id}GET /api/TodoItems/{id} Ottiene un elemento in base all'IDGet an item by ID nessunaNone Elemento attivitàTo-do item
POST /api/TodoItemsPOST /api/TodoItems Aggiunge un nuovo elementoAdd a new item Elemento attivitàTo-do item Elemento attivitàTo-do item
PUT /api/TodoItems/{id}PUT /api/TodoItems/{id} Aggiorna un elemento esistente  Update an existing item   Elemento attivitàTo-do item nessunaNone
Elimina  /api/TodoItems/{id}  DELETE /api/TodoItems/{id}     Eliminare un elemento    Delete an item     nessunaNone nessunaNone

Il diagramma seguente visualizza la struttura dell'app.The following diagram shows the design of the app.

Il client è rappresentato da una casella a sinistra.

PrerequisitiPrerequisites

Creare un progetto WebCreate a web project

  • Scegliere nuovo > progettodal menu file .From the File menu, select New > Project.
  • Selezionare il modello Applicazione Web ASP.NET Core e fare clic su Avanti.Select the ASP.NET Core Web Application template and click Next.
  • Assegnare al progetto il nome TodoApi e fare clic su Crea.Name the project TodoApi and click Create.
  • Nella finestra di dialogo Crea una nuova applicazione Web ASP.NET Core verificare che siano selezionati .net Core e ASP.NET Core 3,1 .In the Create a new ASP.NET Core Web Application dialog, confirm that .NET Core and ASP.NET Core 3.1 are selected. Selezionare il modello API e fare clic su Crea.Select the API template and click Create.

Finestra di dialogo Nuovo progetto di Visual Studio

Testare l'APITest the API

Il modello di progetto crea un'API WeatherForecast.The project template creates a WeatherForecast API. Chiamare il metodo Get da un browser per eseguire il test dell'app.Call the Get method from a browser to test the app.

Premere CTRL+F5 per eseguire l'app.Press Ctrl+F5 to run the app. Visual Studio apre un browser e naviga all'indirizzo https://localhost:<port>/WeatherForecast, dove <port> è un numero di porta selezionato a caso.Visual Studio launches a browser and navigates to https://localhost:<port>/WeatherForecast, where <port> is a randomly chosen port number.

Se in una finestra di dialogo viene chiesto se considerare attendibile il certificato IIS Express, selezionare .If you get a dialog box that asks if you should trust the IIS Express certificate, select Yes. Nella finestra di dialogo Avviso di sicurezza successiva selezionare .In the Security Warning dialog that appears next, select Yes.

Viene restituito un codice JSON simile al seguente:JSON similar to the following is returned:

[
    {
        "date": "2019-07-16T19:04:05.7257911-06:00",
        "temperatureC": 52,
        "temperatureF": 125,
        "summary": "Mild"
    },
    {
        "date": "2019-07-17T19:04:05.7258461-06:00",
        "temperatureC": 36,
        "temperatureF": 96,
        "summary": "Warm"
    },
    {
        "date": "2019-07-18T19:04:05.7258467-06:00",
        "temperatureC": 39,
        "temperatureF": 102,
        "summary": "Cool"
    },
    {
        "date": "2019-07-19T19:04:05.7258471-06:00",
        "temperatureC": 10,
        "temperatureF": 49,
        "summary": "Bracing"
    },
    {
        "date": "2019-07-20T19:04:05.7258474-06:00",
        "temperatureC": -1,
        "temperatureF": 31,
        "summary": "Chilly"
    }
]

Aggiungere una classe del modelloAdd a model class

Un modello è un set di classi che rappresentano i dati gestiti dall'app.A model is a set of classes that represent the data that the app manages. Il modello per questa app è una classe TodoItem singola.The model for this app is a single TodoItem class.

  • In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto.In Solution Explorer, right-click the project. Selezionare Aggiungi > Nuova cartella.Select Add > New Folder. Assegnare il nome Models alla cartella.Name the folder Models.

  • Fare clic con il pulsante destro del mouse sulla cartella Models e scegliere Aggiungi > Classe.Right-click the Models folder and select Add > Class. Assegnare alla classe il nome TodoItem e selezionare Aggiungi.Name the class TodoItem and select Add.

  • Sostituire il codice del modello con il codice seguente:Replace the template code with the following code:

#define First

namespace TodoApi.Models
{
#if First
    #region snippet
    public class TodoItem
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
    }
    #endregion
#else
    // Use this to test you can over-post
    public class TodoItem
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
        public string Secret { get; set; }
    }
#endif
}

La proprietà Id funziona come chiave univoca in un database relazionale.The Id property functions as the unique key in a relational database.

È possibile inserire le classi del modello in qualsiasi punto del progetto, ma per convenzione viene usata la cartella Models.Model classes can go anywhere in the project, but the Models folder is used by convention.

Aggiungere un contesto di databaseAdd a database context

Il contesto di database è la classe principale che coordina le funzionalità di Entity Framework per un modello di dati.The database context is the main class that coordinates Entity Framework functionality for a data model. Questa classe viene creata mediante derivazione dalla classe Microsoft.EntityFrameworkCore.DbContext.This class is created by deriving from the Microsoft.EntityFrameworkCore.DbContext class.

Aggiungere Microsoft.EntityFrameworkCore.SqlServerAdd Microsoft.EntityFrameworkCore.SqlServer

  • Dal menu Strumenti selezionare Gestione pacchetti NuGet > Gestisci pacchetti NuGet per la soluzione.From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
  • Selezionare la scheda Esplora e quindi immettere Microsoft.EntityFrameworkCore.SqlServer nella casella di ricerca.Select the Browse tab, and then enter Microsoft.EntityFrameworkCore.SqlServer in the search box.
  • Nel riquadro sinistro selezionare Microsoft. EntityFrameworkCore. SqlServer .Select Microsoft.EntityFrameworkCore.SqlServer in the left pane.
  • Selezionare la casella di controllo Progetto nel riquadro di destra e quindi selezionare Installa.Select the Project check box in the right pane and then select Install.
  • Usare le istruzioni precedenti per aggiungere il pacchetto NuGet Microsoft.EntityFrameworkCore.InMemory.Use the preceding instructions to add the Microsoft.EntityFrameworkCore.InMemory NuGet package.

Gestione pacchetti NuGet

Aggiungere il contesto del database TodoContextAdd the TodoContext database context

  • Fare clic con il pulsante destro del mouse sulla cartella Models e scegliere Aggiungi > Classe.Right-click the Models folder and select Add > Class. Assegnare alla classe il nome TodoContext e fare clic su Aggiungi.Name the class TodoContext and click Add.
  • Immettere il codice seguente:Enter the following code:

    using Microsoft.EntityFrameworkCore;
    
    namespace TodoApi.Models
    {
        public class TodoContext : DbContext
        {
            public TodoContext(DbContextOptions<TodoContext> options)
                : base(options)
            {
            }
    
            public DbSet<TodoItem> TodoItems { get; set; }
        }
    }
    

Registrare il contesto del databaseRegister the database context

In ASP.NET Core i servizi come il contesto del database devono essere registrati con il contenitore di inserimento delle dipendenze.In ASP.NET Core, services such as the DB context must be registered with the dependency injection (DI) container. Il contenitore rende disponibile il servizio ai controller.The container provides the service to controllers.

Aggiornare Startup.cs con il codice evidenziato seguente:Update Startup.cs with the following highlighted code:

// Unused usings removed
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

namespace TodoApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<TodoContext>(opt =>
               opt.UseInMemoryDatabase("TodoList"));
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

Il codice precedente:The preceding code:

  • Rimuove le dichiarazioni using inutilizzate.Removes unused using declarations.
  • Aggiunge il contesto del database al contenitore di inserimento delle dipendenze.Adds the database context to the DI container.
  • Specifica che il contesto del database userà un database in memoria.Specifies that the database context will use an in-memory database.

Eseguire lo scaffolding di un controllerScaffold a controller

  • Fare clic con il pulsante destro del mouse sulla cartella Controllers.Right-click the Controllers folder.

  • Selezionare aggiungi > nuovo elemento con impalcatura.Select Add > New Scaffolded Item.

  • Selezionare Controller API con azioni, che usa Entity Framework e quindi selezionare Aggiungi.Select API Controller with actions, using Entity Framework, and then select Add.

  • Nella finestra di dialogo Add API Controller with actions, using Entity Framework (Aggiungi controller API con azioni, che usa Entity Framework):In the Add API Controller with actions, using Entity Framework dialog:

    • Selezionare TodoItem (TodoApi. Models) nella classe del modello.Select TodoItem (TodoApi.Models) in the Model class.
    • Selezionare TodoContext (TodoApi. Models) nella classe del contesto dati.Select TodoContext (TodoApi.Models) in the Data context class.
    • Selezionare Aggiungi.Select Add.

Il codice generato:The generated code:

  • Contrassegna la classe con l'attributo [ApiController] .Marks the class with the [ApiController] attribute. L'attributo indica che il controller risponde alle richieste di API Web.This attribute indicates that the controller responds to web API requests. Per informazioni sui comportamenti specifici consentiti dall'attributo, vedere Creare API Web con ASP.NET Core.For information about specific behaviors that the attribute enables, see Creare API Web con ASP.NET Core.
  • Usa l'inserimento delle dipendenze per inserire il contesto del database (TodoContext) nel controller.Uses DI to inject the database context (TodoContext) into the controller. Il contesto di database viene usato in ognuno dei metodi CRUD nel controller.The database context is used in each of the CRUD methods in the controller.

Esaminare il metodo di creazione PostTodoItemExamine the PostTodoItem create method

Sostituire l'istruzione return in PostTodoItem per usare l'operatore nameof:Replace the return statement in the PostTodoItem to use the nameof operator:

// POST: api/TodoItems
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
    _context.TodoItems.Add(todoItem);
    await _context.SaveChangesAsync();

    //return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
    return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
}

Il codice precedente è un metodo HTTP POST, come indicato dall'attributo [HttpPost] .The preceding code is an HTTP POST method, as indicated by the [HttpPost] attribute. Il metodo ottiene il valore dell'elemento attività dal corpo della richiesta HTTP.The method gets the value of the to-do item from the body of the HTTP request.

Il metodo CreatedAtAction:The CreatedAtAction method:

  • Restituisce un codice di stato HTTP 201 in caso di esito positivo.Returns an HTTP 201 status code if successful. HTTP 201 è la risposta standard per un metodo HTTP POST che crea una nuova risorsa nel server.HTTP 201 is the standard response for an HTTP POST method that creates a new resource on the server.
  • Aggiunge un'intestazione Location alla risposta.Adds a Location header to the response. L'intestazione Location specifica l'URI dell'elemento attività appena creato.The Location header specifies the URI of the newly created to-do item. Per altre informazioni, vedere 10.2.2 201 Created.For more information, see 10.2.2 201 Created.
  • Fa riferimento all'azione GetTodoItem per creare l'URI dell'intestazione Location.References the GetTodoItem action to create the Location header's URI. La parola chiave nameof C# viene usata per evitare di impostare il nome dell'azione come hardcoded nella chiamata a CreatedAtAction.The C# nameof keyword is used to avoid hard-coding the action name in the CreatedAtAction call.

Installare PostmanInstall Postman

Questa esercitazione usa Postman per testare l'API Web.This tutorial uses Postman to test the web API.

  • Installare PostmanInstall Postman
  • Avviare l'app Web.Start the web app.
  • Avviare Postman.Start Postman.
  • Disattivare SSL certificate verification (Verifica certificato SSL)Disable SSL certificate verification
    • In File > Impostazioni (schedagenerale ) disabilitare la Verifica del certificato SSL.From File > Settings (General tab), disable SSL certificate verification.

      Avviso

      Riattivare la verifica dei certificati SSL al termine del test del controller.Re-enable SSL certificate verification after testing the controller.

Testare PostTodoItem con PostmanTest PostTodoItem with Postman

  • Creare una nuova richiesta.Create a new request.

  • Impostare il metodo HTTP su POST.Set the HTTP method to POST.

  • Fare clic sulla scheda Body (Corpo).Select the Body tab.

  • Selezionare il pulsante di opzione raw (non elaborato).Select the raw radio button.

  • Impostare il tipo su JSON (application/json) .Set the type to JSON (application/json).

  • Nel corpo della richiesta immettere codice JSON per un elemento attività:In the request body enter JSON for a to-do item:

    {
      "name":"walk dog",
      "isComplete":true
    }
    
  • Selezionare Send (Invia).Select Send.

    Postman con richiesta di creazione

Testare l'URI dell'intestazione della posizioneTest the location header URI

  • Selezionare la scheda Headers (Intestazioni) nel riquadro Response (Risposta).Select the Headers tab in the Response pane.

  • Copiare il valore dell'intestazione Location (Posizione):Copy the Location header value:

    Scheda Headers (Intestazioni) della console Postman

  • Impostare il metodo su GET.Set the method to GET.

  • Incollare l'URI, ad esempio https://localhost:5001/api/TodoItems/1.Paste the URI (for example, https://localhost:5001/api/TodoItems/1).

  • Selezionare Send (Invia).Select Send.

Esaminare i metodi GETExamine the GET methods

Questi metodi implementano due metodi GET:These methods implement two GET endpoints:

  • GET /api/TodoItems
  • GET /api/TodoItems/{id}

Testare l'app chiamando i due endpoint da un browser o da Postman.Test the app by calling the two endpoints from a browser or Postman. Ad esempio:For example:

Una risposta simile alla seguente viene generata dalla chiamata a GetTodoItems:A response similar to the following is produced by the call to GetTodoItems:

[
  {
    "id": 1,
    "name": "Item1",
    "isComplete": false
  }
]

Testare Get con PostmanTest Get with Postman

  • Creare una nuova richiesta.Create a new request.
  • Impostare il metodo HTTP su GET.Set the HTTP method to GET.
  • Impostare l'URL della richiesta su https://localhost:<port>/api/TodoItems.Set the request URL to https://localhost:<port>/api/TodoItems. Ad esempio https://localhost:5001/api/TodoItems.For example, https://localhost:5001/api/TodoItems.
  • Impostare Two pane view (Visualizzazione in due riquadri) in Postman.Set Two pane view in Postman.
  • Selezionare Send (Invia).Select Send.

Questa app usa un database in memoria.This app uses an in-memory database. Se l'app viene arrestata e avviata, la richiesta GET precedente non restituirà alcun dato.If the app is stopped and started, the preceding GET request will not return any data. Se non vengono restituiti dati, eseguire POST per pubblicare i dati nell'app.If no data is returned, POST data to the app.

Routing e percorsi di URLRouting and URL paths

L'attributo [HttpGet] indica un metodo che risponde a una richiesta HTTP GET.The [HttpGet] attribute denotes a method that responds to an HTTP GET request. Il percorso dell'URL per ogni metodo viene costruito nel modo seguente:The URL path for each method is constructed as follows:

  • Iniziare con la stringa di modello nell'attributo Route del controller:Start with the template string in the controller's Route attribute:

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    {
        private readonly TodoContext _context;
    
        public TodoItemsController(TodoContext context)
        {
            _context = context;
        }
    
  • Sostituire [controller] con il nome del controller, ovvero, per convenzione, il nome della classe controller meno il suffisso "Controller".Replace [controller] with the name of the controller, which by convention is the controller class name minus the "Controller" suffix. In questo esempio il nome della classe controller è TodoItemsController, quindi il nome del controller è "TodoItems".For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". Il routing ASP.NET Core non fa distinzione tra maiuscole e minuscole.ASP.NET Core routing is case insensitive.

  • Se l'attributo [HttpGet] ha un modello di route, ad esempio [HttpGet("products")], aggiungerlo al percorso.If the [HttpGet] attribute has a route template (for example, [HttpGet("products")]), append that to the path. In questo esempio non si usa un modello.This sample doesn't use a template. Per altre informazioni, vedere Routing con attributi Http[verb].For more information, see Attribute routing with Http[Verb] attributes.

Nel metodo GetTodoItem seguente, "{id}" è una variabile segnaposto per l'identificatore univoco dell'elemento attività.In the following GetTodoItem method, "{id}" is a placeholder variable for the unique identifier of the to-do item. Quando viene richiamato GetTodoItem, il valore di "{id}" nell'URL viene fornito al metodo nel parametro id.When GetTodoItem is invoked, the value of "{id}" in the URL is provided to the method in its id parameter.

// GET: api/TodoItems/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

Valori restituitiReturn values

Il tipo restituito dei metodi GetTodoItems e GetTodoItem è ActionResult<T>.The return type of the GetTodoItems and GetTodoItem methods is ActionResult<T> type. ASP.NET Core serializza automaticamente l'oggetto su JSON e scrive il codice JSON nel corpo del messaggio di risposta.ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. Il codice di risposta per questo tipo restituito è 200, presupponendo che non esistano eccezioni non gestite.The response code for this return type is 200, assuming there are no unhandled exceptions. Le eccezioni non gestite vengono convertite in errori 5xx.Unhandled exceptions are translated into 5xx errors.

I tipi restituiti ActionResult possono rappresentare un ampio intervallo di codici di stato HTTP.ActionResult return types can represent a wide range of HTTP status codes. Ad esempio, GetTodoItem può restituire due valori di stato diversi:For example, GetTodoItem can return two different status values:

  • Se nessun elemento corrisponde all'ID richiesto, il metodo restituisce un codice di errore 404 NotFound.If no item matches the requested ID, the method returns a 404 NotFound error code.
  • In caso contrario, il metodo restituisce il codice 200 con un corpo della risposta JSON.Otherwise, the method returns 200 with a JSON response body. La restituzione di item risulta in una risposta HTTP 200.Returning item results in an HTTP 200 response.

Metodo PutTodoItemThe PutTodoItem method

Esaminare il metodo PutTodoItem:Examine the PutTodoItem method:

// PUT: api/TodoItems/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id)
    {
        return BadRequest();
    }

    _context.Entry(todoItem).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!TodoItemExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

PutTodoItem è simile a PostTodoItem ma usa la richiesta HTTP PUT.PutTodoItem is similar to PostTodoItem, except it uses HTTP PUT. La risposta è 204 (No Content).The response is 204 (No Content). In base alla specifica HTTP, una richiesta PUT richiede che il client invii l'intera entità aggiornata e non solo le modifiche.According to the HTTP specification, a PUT request requires the client to send the entire updated entity, not just the changes. Per supportare gli aggiornamenti parziali, usare HTTP PATCH.To support partial updates, use HTTP PATCH.

Se si riceve un errore chiamando PutTodoItem, chiamare GET per verificare che il database includa un elemento.If you get an error calling PutTodoItem, call GET to ensure there's an item in the database.

Testare il metodo PutTodoItemTest the PutTodoItem method

Questo esempio usa un database in memoria che deve essere inizializzato ogni volta che l'app viene avviata.This sample uses an in-memory database that must be initialized each time the app is started. Deve esistere un elemento nel database prima di eseguire una chiamata PUT.There must be an item in the database before you make a PUT call. Chiamare GET per assicurarsi che sia presente un elemento nel database prima di eseguire una chiamata PUT.Call GET to insure there's an item in the database before making a PUT call.

Aggiornare l'elemento attività con ID = 1 e impostarne il nome su "feed fish":Update the to-do item that has ID = 1 and set its name to "feed fish":

  {
    "ID":1,
    "name":"feed fish",
    "isComplete":true
  }

L'immagine seguente visualizza l'aggiornamento di Postman:The following image shows the Postman update:

Console Postman con risposta 204 (No Content)

Metodo DeleteTodoItemThe DeleteTodoItem method

Esaminare il metodo DeleteTodoItem:Examine the DeleteTodoItem method:

// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<ActionResult<TodoItem>> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);
    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return todoItem;
}

Testare il metodo DeleteTodoItemTest the DeleteTodoItem method

Usare Postman per eliminare un elemento attività:Use Postman to delete a to-do item:

  • Impostare il metodo su DELETE.Set the method to DELETE.
  • Impostare l'URI dell'oggetto da eliminare, ad esempio https://localhost:5001/api/TodoItems/1.Set the URI of the object to delete (for example https://localhost:5001/api/TodoItems/1).
  • Selezionare Send (Invia).Select Send.

Chiamare l'API Web con JavaScriptCall the web API with JavaScript

Vedere esercitazione: chiamare un'API web ASP.NET Core con JavaScript.See Tutorial: Call an ASP.NET Core web API with JavaScript.

In questa esercitazione si imparerà a:In this tutorial, you learn how to:

  • Creare un progetto di API Web.Create a web API project.
  • Aggiungere una classe modello e un contesto di database.Add a model class and a database context.
  • Aggiungere un controller.Add a controller.
  • Aggiungere metodi CRUD.Add CRUD methods.
  • Configurare routing e percorsi URL.Configure routing and URL paths.
  • Specificare valori restituiti.Specify return values.
  • Chiamare l'API Web con Postman.Call the web API with Postman.
  • Chiamare l'API Web con JavaScript.Call the web API with JavaScript.

Al termine si dispone di un'API web che può gestire gli elementi di tipo "attività" archiviati in un database relazionale.At the end, you have a web API that can manage "to-do" items stored in a relational database.

Panoramica diOverview

Questa esercitazione consente di creare l'API seguente:This tutorial creates the following API:

APIAPI DescrizioneDescription Testo della richiestaRequest body Corpo della rispostaResponse body
GET /api/TodoItemsGET /api/TodoItems Ottiene tutti gli elementi attivitàGet all to-do items nessunaNone Matrice di elementi attivitàArray of to-do items
GET /api/TodoItems/{id}GET /api/TodoItems/{id} Ottiene un elemento in base all'IDGet an item by ID nessunaNone Elemento attivitàTo-do item
POST /api/TodoItemsPOST /api/TodoItems Aggiunge un nuovo elementoAdd a new item Elemento attivitàTo-do item Elemento attivitàTo-do item
PUT /api/TodoItems/{id}PUT /api/TodoItems/{id} Aggiorna un elemento esistente  Update an existing item   Elemento attivitàTo-do item nessunaNone
Elimina  /api/TodoItems/{id}  DELETE /api/TodoItems/{id}     Eliminare un elemento    Delete an item     nessunaNone nessunaNone

Il diagramma seguente visualizza la struttura dell'app.The following diagram shows the design of the app.

Il client è rappresentato da una casella a sinistra.

PrerequisitiPrerequisites

Avviso

Se si usa Visual Studio 2017, vedere dotnet/sdk issue #3124 per informazioni sulle versioni di .NET Core SDK che non funzionano con Visual Studio.If you use Visual Studio 2017, see dotnet/sdk issue #3124 for information about .NET Core SDK versions that don't work with Visual Studio.

Creare un progetto WebCreate a web project

  • Scegliere nuovo > progettodal menu file .From the File menu, select New > Project.
  • Selezionare il modello Applicazione Web ASP.NET Core e fare clic su Avanti.Select the ASP.NET Core Web Application template and click Next.
  • Assegnare al progetto il nome TodoApi e fare clic su Crea.Name the project TodoApi and click Create.
  • Nella finestra di dialogo Crea una nuova applicazione Web ASP.NET Core verificare che siano selezionati .NET Core e ASP.NET Core 2.2.In the Create a new ASP.NET Core Web Application dialog, confirm that .NET Core and ASP.NET Core 2.2 are selected. Selezionare il modello API e fare clic su Crea.Select the API template and click Create. Non selezionare Abilita supporto Docker.Don't select Enable Docker Support.

Finestra di dialogo Nuovo progetto di Visual Studio

Testare l'APITest the API

Il modello di progetto crea un'API values.The project template creates a values API. Chiamare il metodo Get da un browser per eseguire il test dell'app.Call the Get method from a browser to test the app.

Premere CTRL+F5 per eseguire l'app.Press Ctrl+F5 to run the app. Visual Studio apre un browser e naviga all'indirizzo https://localhost:<port>/api/values, dove <port> è un numero di porta selezionato a caso.Visual Studio launches a browser and navigates to https://localhost:<port>/api/values, where <port> is a randomly chosen port number.

Se in una finestra di dialogo viene chiesto se considerare attendibile il certificato IIS Express, selezionare .If you get a dialog box that asks if you should trust the IIS Express certificate, select Yes. Nella finestra di dialogo Avviso di sicurezza successiva selezionare .In the Security Warning dialog that appears next, select Yes.

Viene restituito il codice JSON seguente:The following JSON is returned:

["value1","value2"]

Aggiungere una classe del modelloAdd a model class

Un modello è un set di classi che rappresentano i dati gestiti dall'app.A model is a set of classes that represent the data that the app manages. Il modello per questa app è una classe TodoItem singola.The model for this app is a single TodoItem class.

  • In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto.In Solution Explorer, right-click the project. Selezionare Aggiungi > Nuova cartella.Select Add > New Folder. Assegnare il nome Models alla cartella.Name the folder Models.

  • Fare clic con il pulsante destro del mouse sulla cartella Models e scegliere Aggiungi > Classe.Right-click the Models folder and select Add > Class. Assegnare alla classe il nome TodoItem e selezionare Aggiungi.Name the class TodoItem and select Add.

  • Sostituire il codice del modello con il codice seguente:Replace the template code with the following code:

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
    }
}

La proprietà Id funziona come chiave univoca in un database relazionale.The Id property functions as the unique key in a relational database.

È possibile inserire le classi del modello in qualsiasi punto del progetto, ma per convenzione viene usata la cartella Models.Model classes can go anywhere in the project, but the Models folder is used by convention.

Aggiungere un contesto di databaseAdd a database context

Il contesto di database è la classe principale che coordina le funzionalità di Entity Framework per un modello di dati.The database context is the main class that coordinates Entity Framework functionality for a data model. Questa classe viene creata mediante derivazione dalla classe Microsoft.EntityFrameworkCore.DbContext.This class is created by deriving from the Microsoft.EntityFrameworkCore.DbContext class.

  • Fare clic con il pulsante destro del mouse sulla cartella Models e scegliere Aggiungi > Classe.Right-click the Models folder and select Add > Class. Assegnare alla classe il nome TodoContext e fare clic su Aggiungi.Name the class TodoContext and click Add.
  • Sostituire il codice del modello con il codice seguente:Replace the template code with the following code:

    using Microsoft.EntityFrameworkCore;
    
    namespace TodoApi.Models
    {
        public class TodoContext : DbContext
        {
            public TodoContext(DbContextOptions<TodoContext> options)
                : base(options)
            {
            }
    
            public DbSet<TodoItem> TodoItems { get; set; }
        }
    }
    

Registrare il contesto del databaseRegister the database context

In ASP.NET Core i servizi come il contesto del database devono essere registrati con il contenitore di inserimento delle dipendenze.In ASP.NET Core, services such as the DB context must be registered with the dependency injection (DI) container. Il contenitore rende disponibile il servizio ai controller.The container provides the service to controllers.

Aggiornare Startup.cs con il codice evidenziato seguente:Update Startup.cs with the following highlighted code:

// Unused usings removed
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using TodoApi.Models;

namespace TodoApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the 
        //container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<TodoContext>(opt =>
                opt.UseInMemoryDatabase("TodoList"));
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP 
        //request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for 
                // production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}

Il codice precedente:The preceding code:

  • Rimuove le dichiarazioni using inutilizzate.Removes unused using declarations.
  • Aggiunge il contesto del database al contenitore di inserimento delle dipendenze.Adds the database context to the DI container.
  • Specifica che il contesto del database userà un database in memoria.Specifies that the database context will use an in-memory database.

Aggiungere un controllerAdd a controller

  • Fare clic con il pulsante destro del mouse sulla cartella Controllers.Right-click the Controllers folder.

  • Selezionare aggiungi > nuovo elemento.Select Add > New Item.

  • Nella finestra di dialogo Aggiungi nuovo elemento selezionare il modello API Controller Class (Classe controller API).In the Add New Item dialog, select the API Controller Class template.

  • Assegnare alla classe il nome TodoController e selezionare Aggiungi.Name the class TodoController, and select Add.

    Finestra di dialogo Aggiungi nuovo elemento con controller nella casella di ricerca e controller API Web selezionato

  • Sostituire il codice del modello con il codice seguente:Replace the template code with the following code:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using TodoApi.Models;
    
    namespace TodoApi.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class TodoController : ControllerBase
        {
            private readonly TodoContext _context;
    
            public TodoController(TodoContext context)
            {
                _context = context;
    
                if (_context.TodoItems.Count() == 0)
                {
                    // Create a new TodoItem if collection is empty,
                    // which means you can't delete all TodoItems.
                    _context.TodoItems.Add(new TodoItem { Name = "Item1" });
                    _context.SaveChanges();
                }
            }
        }
    }
    

Il codice precedente:The preceding code:

  • Definisce una classe controller API senza metodi.Defines an API controller class without methods.
  • Contrassegna la classe con l'attributo [ApiController] .Marks the class with the [ApiController] attribute. L'attributo indica che il controller risponde alle richieste di API Web.This attribute indicates that the controller responds to web API requests. Per informazioni sui comportamenti specifici consentiti dall'attributo, vedere Creare API Web con ASP.NET Core.For information about specific behaviors that the attribute enables, see Creare API Web con ASP.NET Core.
  • Usa l'inserimento delle dipendenze per inserire il contesto del database (TodoContext) nel controller.Uses DI to inject the database context (TodoContext) into the controller. Il contesto di database viene usato in ognuno dei metodi CRUD nel controller.The database context is used in each of the CRUD methods in the controller.
  • Aggiunge un elemento denominato Item1 al database se il database è vuoto.Adds an item named Item1 to the database if the database is empty. Questo codice si trova nel costruttore, quindi viene eseguito ogni volta che è presente una nuova richiesta HTTP.This code is in the constructor, so it runs every time there's a new HTTP request. Se si eliminano tutti gli elementi, il costruttore crea di nuovo Item1 quando viene nuovamente chiamato un metodo API.If you delete all items, the constructor creates Item1 again the next time an API method is called. Potrebbe pertanto sembrare che l'eliminazione non abbia funzionato, mentre di fatto ha funzionato.So it may look like the deletion didn't work when it actually did work.

Aggiungere metodi GetAdd Get methods

Per specificare un'API che recupera elementi attività, aggiungere i metodi seguenti alla classe TodoController:To provide an API that retrieves to-do items, add the following methods to the TodoController class:

// GET: api/Todo
[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItem>>> GetTodoItems()
{
    return await _context.TodoItems.ToListAsync();
}

// GET: api/Todo/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

Questi metodi implementano due metodi GET:These methods implement two GET endpoints:

  • GET /api/todo
  • GET /api/todo/{id}

Arrestare l'app se è ancora in esecuzione.Stop the app if it's still running. Quindi eseguirla di nuovo per includere le modifiche più recenti.Then run it again to include the latest changes.

Testare l'app chiamando i due endpoint da un browser.Test the app by calling the two endpoints from a browser. Ad esempio:For example:

  • https://localhost:<port>/api/todo
  • https://localhost:<port>/api/todo/1

La chiamata a GetTodoItems genera la risposta HTTP seguente:The following HTTP response is produced by the call to GetTodoItems:

[
  {
    "id": 1,
    "name": "Item1",
    "isComplete": false
  }
]

Routing e percorsi di URLRouting and URL paths

L'attributo [HttpGet] indica un metodo che risponde a una richiesta HTTP GET.The [HttpGet] attribute denotes a method that responds to an HTTP GET request. Il percorso dell'URL per ogni metodo viene costruito nel modo seguente:The URL path for each method is constructed as follows:

  • Iniziare con la stringa di modello nell'attributo Route del controller:Start with the template string in the controller's Route attribute:

    namespace TodoApi.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class TodoController : ControllerBase
        {
            private readonly TodoContext _context;
    
  • Sostituire [controller] con il nome del controller, ovvero, per convenzione, il nome della classe controller meno il suffisso "Controller".Replace [controller] with the name of the controller, which by convention is the controller class name minus the "Controller" suffix. In questo esempio il nome della classe controller è TodoController, pertanto il nome del controller è "todo".For this sample, the controller class name is TodoController, so the controller name is "todo". Il routing ASP.NET Core non fa distinzione tra maiuscole e minuscole.ASP.NET Core routing is case insensitive.

  • Se l'attributo [HttpGet] ha un modello di route, ad esempio [HttpGet("products")], aggiungerlo al percorso.If the [HttpGet] attribute has a route template (for example, [HttpGet("products")]), append that to the path. In questo esempio non si usa un modello.This sample doesn't use a template. Per altre informazioni, vedere Routing con attributi Http[verb].For more information, see Attribute routing with Http[Verb] attributes.

Nel metodo GetTodoItem seguente, "{id}" è una variabile segnaposto per l'identificatore univoco dell'elemento attività.In the following GetTodoItem method, "{id}" is a placeholder variable for the unique identifier of the to-do item. Quando viene chiamato GetTodoItem, il valore di "{id}" viene specificato per il metodo nel rispettivo parametro id.When GetTodoItem is invoked, the value of "{id}" in the URL is provided to the method in itsid parameter.

// GET: api/Todo/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

Valori restituitiReturn values

Il tipo restituito dei metodi GetTodoItems e GetTodoItem è ActionResult<T>.The return type of the GetTodoItems and GetTodoItem methods is ActionResult<T> type. ASP.NET Core serializza automaticamente l'oggetto su JSON e scrive il codice JSON nel corpo del messaggio di risposta.ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. Il codice di risposta per questo tipo restituito è 200, presupponendo che non esistano eccezioni non gestite.The response code for this return type is 200, assuming there are no unhandled exceptions. Le eccezioni non gestite vengono convertite in errori 5xx.Unhandled exceptions are translated into 5xx errors.

I tipi restituiti ActionResult possono rappresentare un ampio intervallo di codici di stato HTTP.ActionResult return types can represent a wide range of HTTP status codes. Ad esempio, GetTodoItem può restituire due valori di stato diversi:For example, GetTodoItem can return two different status values:

  • Se nessun elemento corrisponde all'ID richiesto, il metodo restituisce un codice di errore 404 NotFound.If no item matches the requested ID, the method returns a 404 NotFound error code.
  • In caso contrario, il metodo restituisce il codice 200 con un corpo della risposta JSON.Otherwise, the method returns 200 with a JSON response body. La restituzione di item risulta in una risposta HTTP 200.Returning item results in an HTTP 200 response.

Testare il metodo GetTodoItemsTest the GetTodoItems method

Questa esercitazione usa Postman per testare l'API Web.This tutorial uses Postman to test the web API.

  • Installare il post.Install Postman.
  • Avviare l'app Web.Start the web app.
  • Avviare Postman.Start Postman.
  • Disabilitare la Verifica del certificato SSL.Disable SSL certificate verification.
  • In File > Impostazioni (schedagenerale ) disabilitare la Verifica del certificato SSL.From File > Settings (General tab), disable SSL certificate verification.

Avviso

Riattivare la verifica dei certificati SSL al termine del test del controller.Re-enable SSL certificate verification after testing the controller.

  • Creare una nuova richiesta.Create a new request.
    • Impostare il metodo HTTP su GET.Set the HTTP method to GET.
    • Impostare l'URL della richiesta su https://localhost:<port>/api/todo.Set the request URL to https://localhost:<port>/api/todo. Ad esempio https://localhost:5001/api/todo.For example, https://localhost:5001/api/todo.
  • Impostare Two pane view (Visualizzazione in due riquadri) in Postman.Set Two pane view in Postman.
  • Selezionare Send (Invia).Select Send.

Postman con richiesta GET

Aggiungere un metodo CreateAdd a Create method

Aggiungere il metodo PostTodoItem seguente in Controllers/TodoController.cs:Add the following PostTodoItem method inside of Controllers/TodoController.cs:

// POST: api/Todo
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item);
}

Il codice precedente è un metodo HTTP POST, come indicato dall'attributo [HttpPost] .The preceding code is an HTTP POST method, as indicated by the [HttpPost] attribute. Il metodo ottiene il valore dell'elemento attività dal corpo della richiesta HTTP.The method gets the value of the to-do item from the body of the HTTP request.

Il metodo CreatedAtAction:The CreatedAtAction method:

  • Restituisce un codice di stato HTTP 201 in caso di esito positivo.Returns an HTTP 201 status code, if successful. HTTP 201 è la risposta standard per un metodo HTTP POST che crea una nuova risorsa nel server.HTTP 201 is the standard response for an HTTP POST method that creates a new resource on the server.

  • Aggiunge un'intestazione Location alla risposta.Adds a Location header to the response. L'intestazione Location specifica l'URI dell'elemento attività appena creato.The Location header specifies the URI of the newly created to-do item. Per altre informazioni, vedere 10.2.2 201 Created.For more information, see 10.2.2 201 Created.

  • Fa riferimento all'azione GetTodoItem per creare l'URI dell'intestazione Location.References the GetTodoItem action to create the Location header's URI. La parola chiave nameof C# viene usata per evitare di impostare il nome dell'azione come hardcoded nella chiamata a CreatedAtAction.The C# nameof keyword is used to avoid hard-coding the action name in the CreatedAtAction call.

    // GET: api/Todo/5
    [HttpGet("{id}")]
    public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
    {
        var todoItem = await _context.TodoItems.FindAsync(id);
    
        if (todoItem == null)
        {
            return NotFound();
        }
    
        return todoItem;
    }
    

Testare il metodo PostTodoItemTest the PostTodoItem method

  • Compilazione del progetto.Build the project.

  • In Postman impostare il metodo HTTP su POST.In Postman, set the HTTP method to POST.

  • Fare clic sulla scheda Body (Corpo).Select the Body tab.

  • Selezionare il pulsante di opzione raw (non elaborato).Select the raw radio button.

  • Impostare il tipo su JSON (application/json) .Set the type to JSON (application/json).

  • Nel corpo della richiesta immettere codice JSON per un elemento attività:In the request body enter JSON for a to-do item:

    {
      "name":"walk dog",
      "isComplete":true
    }
    
  • Selezionare Send (Invia).Select Send.

    Postman con richiesta di creazione

    Se viene visualizzato un errore HTTP 405 - Metodo non consentito, è probabile che il progetto non sia stato compilato dopo l'aggiunta del metodo PostTodoItem.If you get a 405 Method Not Allowed error, it's probably the result of not compiling the project after adding the PostTodoItem method.

Testare l'URI dell'intestazione della posizioneTest the location header URI

  • Selezionare la scheda Headers (Intestazioni) nel riquadro Response (Risposta).Select the Headers tab in the Response pane.

  • Copiare il valore dell'intestazione Location (Posizione):Copy the Location header value:

    Scheda Headers (Intestazioni) della console Postman

  • Impostare il metodo su GET.Set the method to GET.

  • Incollare l'URI, ad esempio https://localhost:5001/api/Todo/2.Paste the URI (for example, https://localhost:5001/api/Todo/2).

  • Selezionare Send (Invia).Select Send.

Aggiungere un metodo PutTodoItemAdd a PutTodoItem method

Aggiungere il metodo PutTodoItem seguente:Add the following PutTodoItem method:

// PUT: api/Todo/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem item)
{
    if (id != item.Id)
    {
        return BadRequest();
    }

    _context.Entry(item).State = EntityState.Modified;
    await _context.SaveChangesAsync();

    return NoContent();
}

PutTodoItem è simile a PostTodoItem ma usa la richiesta HTTP PUT.PutTodoItem is similar to PostTodoItem, except it uses HTTP PUT. La risposta è 204 (No Content).The response is 204 (No Content). In base alla specifica HTTP, una richiesta PUT richiede che il client invii l'intera entità aggiornata e non solo le modifiche.According to the HTTP specification, a PUT request requires the client to send the entire updated entity, not just the changes. Per supportare gli aggiornamenti parziali, usare HTTP PATCH.To support partial updates, use HTTP PATCH.

Se si riceve un errore chiamando PutTodoItem, chiamare GET per verificare che il database includa un elemento.If you get an error calling PutTodoItem, call GET to ensure there's an item in the database.

Testare il metodo PutTodoItemTest the PutTodoItem method

Questo esempio usa un database in memoria che deve essere inizializzato ogni volta che l'app viene avviata.This sample uses an in-memory database that must be initialized each time the app is started. Deve esistere un elemento nel database prima di eseguire una chiamata PUT.There must be an item in the database before you make a PUT call. Chiamare GET per assicurarsi che sia presente un elemento nel database prima di eseguire una chiamata PUT.Call GET to insure there's an item in the database before making a PUT call.

Aggiornare l'elemento attività con id = 1 e impostarne il nome su "feed fish":Update the to-do item that has id = 1 and set its name to "feed fish":

  {
    "ID":1,
    "name":"feed fish",
    "isComplete":true
  }

L'immagine seguente visualizza l'aggiornamento di Postman:The following image shows the Postman update:

Console Postman con risposta 204 (No Content)

Aggiungere un metodo DeleteTodoItemAdd a DeleteTodoItem method

Aggiungere il metodo DeleteTodoItem seguente:Add the following DeleteTodoItem method:

// DELETE: api/Todo/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return NoContent();
}

La risposta DeleteTodoItem è 204 (No Content).The DeleteTodoItem response is 204 (No Content).

Testare il metodo DeleteTodoItemTest the DeleteTodoItem method

Usare Postman per eliminare un elemento attività:Use Postman to delete a to-do item:

  • Impostare il metodo su DELETE.Set the method to DELETE.
  • Impostare l'URI dell'oggetto da eliminare, ad esempio https://localhost:5001/api/todo/1.Set the URI of the object to delete (for example https://localhost:5001/api/todo/1).
  • Selezionare Send (Invia).Select Send.

L'app di esempio consente di eliminare tutti gli elementi.The sample app allows you to delete all the items. Quando viene eliminato l'ultimo elemento, tuttavia, ne viene creato uno nuovo dal costruttore della classe modello alla successiva chiamata dell'API.However, when the last item is deleted, a new one is created by the model class constructor the next time the API is called.

Chiamare l'API Web con JavaScriptCall the web API with JavaScript

In questa sezione viene aggiunta una pagina HTML che usa JavaScript per chiamare l'API Web.In this section, an HTML page is added that uses JavaScript to call the web API. jQuery avvia la richiesta.jQuery initiates the request. JavaScript aggiorna la pagina con i dettagli della risposta dell'API Web.JavaScript updates the page with the details from the web API's response.

Configurare l'app per servire file statici e abilitare il mapping del file predefinito aggiornando Startup.cs con il codice evidenziato seguente:Configure the app to serve static files and enable default file mapping by updating Startup.cs with the following highlighted code:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        // The default HSTS value is 30 days. You may want to change this for 
        // production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseDefaultFiles();
    app.UseStaticFiles();
    app.UseHttpsRedirection();
    app.UseMvc();
}

Creare una cartella wwwroot nella directory del progetto.Create a wwwroot folder in the project directory.

Aggiungere un file HTML denominato index.html alla directory wwwroot.Add an HTML file named index.html to the wwwroot directory. Sostituire il contenuto con il markup seguente:Replace its contents with the following markup:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>To-do CRUD</title>
    <style>
        input[type='submit'], button, [aria-label] {
            cursor: pointer;
        }

        #spoiler {
            display: none;
        }

        table {
            font-family: Arial, sans-serif;
            border: 1px solid;
            border-collapse: collapse;
        }

        th {
            background-color: #0066CC;
            color: white;
        }

        td {
            border: 1px solid;
            padding: 5px;
        }
    </style>
</head>
<body>
    <h1>To-do CRUD</h1>
    <h3>Add</h3>
    <form action="javascript:void(0);" method="POST" onsubmit="addItem()">
        <input type="text" id="add-name" placeholder="New to-do">
        <input type="submit" value="Add">
    </form>

    <div id="spoiler">
        <h3>Edit</h3>
        <form class="my-form">
            <input type="hidden" id="edit-id">
            <input type="checkbox" id="edit-isComplete">
            <input type="text" id="edit-name">
            <input type="submit" value="Save">
            <a onclick="closeInput()" aria-label="Close">&#10006;</a>
        </form>
    </div>

    <p id="counter"></p>

    <table>
        <tr>
            <th>Is Complete</th>
            <th>Name</th>
            <th></th>
            <th></th>
        </tr>
        <tbody id="todos"></tbody>
    </table>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"
            integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
            crossorigin="anonymous"></script>
    <script src="site.js"></script>
</body>
</html>

Aggiungere un file JavaScript con nome site.js alla directory wwwroot.Add a JavaScript file named site.js to the wwwroot directory. Sostituire il contenuto con il codice seguente:Replace its contents with the following code:

const uri = "api/todo";
let todos = null;
function getCount(data) {
  const el = $("#counter");
  let name = "to-do";
  if (data) {
    if (data > 1) {
      name = "to-dos";
    }
    el.text(data + " " + name);
  } else {
    el.text("No " + name);
  }
}

$(document).ready(function() {
  getData();
});

function getData() {
  $.ajax({
    type: "GET",
    url: uri,
    cache: false,
    success: function(data) {
      const tBody = $("#todos");

      $(tBody).empty();

      getCount(data.length);

      $.each(data, function(key, item) {
        const tr = $("<tr></tr>")
          .append(
            $("<td></td>").append(
              $("<input/>", {
                type: "checkbox",
                disabled: true,
                checked: item.isComplete
              })
            )
          )
          .append($("<td></td>").text(item.name))
          .append(
            $("<td></td>").append(
              $("<button>Edit</button>").on("click", function() {
                editItem(item.id);
              })
            )
          )
          .append(
            $("<td></td>").append(
              $("<button>Delete</button>").on("click", function() {
                deleteItem(item.id);
              })
            )
          );

        tr.appendTo(tBody);
      });

      todos = data;
    }
  });
}

function addItem() {
  const item = {
    name: $("#add-name").val(),
    isComplete: false
  };

  $.ajax({
    type: "POST",
    accepts: "application/json",
    url: uri,
    contentType: "application/json",
    data: JSON.stringify(item),
    error: function(jqXHR, textStatus, errorThrown) {
      alert("Something went wrong!");
    },
    success: function(result) {
      getData();
      $("#add-name").val("");
    }
  });
}

function deleteItem(id) {
  $.ajax({
    url: uri + "/" + id,
    type: "DELETE",
    success: function(result) {
      getData();
    }
  });
}

function editItem(id) {
  $.each(todos, function(key, item) {
    if (item.id === id) {
      $("#edit-name").val(item.name);
      $("#edit-id").val(item.id);
      $("#edit-isComplete")[0].checked = item.isComplete;
    }
  });
  $("#spoiler").css({ display: "block" });
}

$(".my-form").on("submit", function() {
  const item = {
    name: $("#edit-name").val(),
    isComplete: $("#edit-isComplete").is(":checked"),
    id: $("#edit-id").val()
  };

  $.ajax({
    url: uri + "/" + $("#edit-id").val(),
    type: "PUT",
    accepts: "application/json",
    contentType: "application/json",
    data: JSON.stringify(item),
    success: function(result) {
      getData();
    }
  });

  closeInput();
  return false;
});

function closeInput() {
  $("#spoiler").css({ display: "none" });
}

Può essere necessario modificare le impostazioni di avvio del progetto ASP.NET Core per il test della pagina HTML in locale:A change to the ASP.NET Core project's launch settings may be required to test the HTML page locally:

  • Aprire Properties\launchSettings.json.Open Properties\launchSettings.json.
  • Rimuovere la proprietà launchUrl per forzare l'app ad aprire index.html, il file predefinito del progetto.Remove the launchUrl property to force the app to open at index.html—the project's default file.

In questo esempio vengono chiamati tutti i metodi CRUD dell'API Web.This sample calls all of the CRUD methods of the web API. Di seguito sono incluse le spiegazioni delle chiamate all'API.Following are explanations of the calls to the API.

Ottenere un elenco di elementi attivitàGet a list of to-do items

jQuery invia una richiesta HTTP GET all'API Web, che restituisce JSON che rappresenta una matrice di elementi attività.jQuery sends an HTTP GET request to the web API, which returns JSON representing an array of to-do items. La funzione di callback success viene chiamata se la richiesta ha esito positivo.The success callback function is invoked if the request succeeds. Nel callback il modello DOM viene aggiornato con le informazioni dell'elemento attività.In the callback, the DOM is updated with the to-do information.

$(document).ready(function() {
  getData();
});

function getData() {
  $.ajax({
    type: "GET",
    url: uri,
    cache: false,
    success: function(data) {
      const tBody = $("#todos");

      $(tBody).empty();

      getCount(data.length);

      $.each(data, function(key, item) {
        const tr = $("<tr></tr>")
          .append(
            $("<td></td>").append(
              $("<input/>", {
                type: "checkbox",
                disabled: true,
                checked: item.isComplete
              })
            )
          )
          .append($("<td></td>").text(item.name))
          .append(
            $("<td></td>").append(
              $("<button>Edit</button>").on("click", function() {
                editItem(item.id);
              })
            )
          )
          .append(
            $("<td></td>").append(
              $("<button>Delete</button>").on("click", function() {
                deleteItem(item.id);
              })
            )
          );

        tr.appendTo(tBody);
      });

      todos = data;
    }
  });
}

Aggiungere un elemento attivitàAdd a to-do item

jQuery invia una richiesta HTTP POST con l'elemento attività nel corpo della richiesta.jQuery sends an HTTP POST request with the to-do item in the request body. Le opzioni accepts e contentType sono impostate su application/json per specificare il tipo di supporto ricevuto e inviato.The accepts and contentType options are set to application/json to specify the media type being received and sent. L'elemento attività viene convertito in JSON usando JSON.stringify.The to-do item is converted to JSON by using JSON.stringify. Quando l'API restituisce un codice di stato di esecuzione riuscita, viene chiamata la funzione getData per aggiornare la tabella HTML.When the API returns a successful status code, the getData function is invoked to update the HTML table.

function addItem() {
  const item = {
    name: $("#add-name").val(),
    isComplete: false
  };

  $.ajax({
    type: "POST",
    accepts: "application/json",
    url: uri,
    contentType: "application/json",
    data: JSON.stringify(item),
    error: function(jqXHR, textStatus, errorThrown) {
      alert("Something went wrong!");
    },
    success: function(result) {
      getData();
      $("#add-name").val("");
    }
  });
}

Aggiornare un elemento attivitàUpdate a to-do item

L'aggiornamento di un elemento attività è simile all'aggiunta di un elemento di questo tipo.Updating a to-do item is similar to adding one. L'url cambia per includere l'identificatore univoco dell'elemento e type è PUT.The url changes to add the unique identifier of the item, and the type is PUT.

$.ajax({
  url: uri + "/" + $("#edit-id").val(),
  type: "PUT",
  accepts: "application/json",
  contentType: "application/json",
  data: JSON.stringify(item),
  success: function(result) {
    getData();
  }
});

Eliminare un elemento attivitàDelete a to-do item

È possibile eliminare un elemento attività impostando type su DELETE nella chiamata AJAX e specificando l'identificatore univoco dell'elemento nell'URL.Deleting a to-do item is accomplished by setting the type on the AJAX call to DELETE and specifying the item's unique identifier in the URL.

$.ajax({
  url: uri + "/" + id,
  type: "DELETE",
  success: function(result) {
    getData();
  }
});

Aggiungere il supporto per l'autenticazione a un'API WebAdd authentication support to a web API

ASP.NET Core identità aggiunge la funzionalità di accesso dell'interfaccia utente per ASP.NET Core app Web.ASP.NET Core Identity adds user interface (UI) login functionality to ASP.NET Core web apps. Per proteggere le API Web e le Spa, usare uno dei seguenti elementi:To secure web APIs and SPAs, use one of the following:

IdentityServer4 è un Framework di OpenID Connect e OAuth 2,0 per ASP.NET Core 3,0.IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core 3.0. IdentityServer4 Abilita le funzionalità di sicurezza seguenti:IdentityServer4 enables the following security features:

  • Autenticazione come servizio (AaaS)Authentication as a Service (AaaS)
  • Single Sign-on/off (SSO) su più tipi di applicazioneSingle sign-on/off (SSO) over multiple application types
  • Controllo di accesso per le APIAccess control for APIs
  • Gateway federativoFederation Gateway

Per ulteriori informazioni, vedere Welcome to IdentityServer4.For more information, see Welcome to IdentityServer4.

Risorse aggiuntiveAdditional resources

Visualizzare o scaricare il codice di esempio per questa esercitazione.View or download sample code for this tutorial. Vedere come scaricare un esempio.See how to download.

Per ulteriori informazioni, vedere le seguenti risorse:For more information, see the following resources: