Creare un'API Web con ASP.NET Core e MongoDBCreate a web API with ASP.NET Core and MongoDB

Di Pratik Khandelwal e Scott AddieBy Pratik Khandelwal and Scott Addie

Questa esercitazione crea un'API Web che esegue operazioni di creazione, lettura, aggiornamento ed eliminazione (CRUD) su un database NoSQL MongoDB.This tutorial creates a web API that performs Create, Read, Update, and Delete (CRUD) operations on a MongoDB NoSQL database.

In questa esercitazione verranno illustrate le procedure per:In this tutorial, you learn how to:

  • Configurare MongoDBConfigure MongoDB
  • Creare un database MongoDBCreate a MongoDB database
  • Definire una raccolta e uno schema MongoDBDefine a MongoDB collection and schema
  • Eseguire operazioni CRUD di MongoDB da un'API WebPerform MongoDB CRUD operations from a web API
  • Personalizzare la serializzazione JSONCustomize JSON serialization

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

PrerequisitiPrerequisites

Configurare MongoDBConfigure MongoDB

Se si usa Windows, MongoDB viene installato in C: \ programmi \ MongoDB per impostazione predefinita.If using Windows, MongoDB is installed at C:\Program Files\MongoDB by default. Aggiungere C: \ Program Files \ MongoDB \ server \ <version_number> \ bin alla Path variabile di ambiente.Add C:\Program Files\MongoDB\Server\<version_number>\bin to the Path environment variable. Questa modifica consente l'accesso MongoDB da qualsiasi posizione nel computer di sviluppo.This change enables MongoDB access from anywhere on your development machine.

Usare la shell mongo nelle procedure seguenti per creare un database, creare le raccolte e archiviare i documenti.Use the mongo Shell in the following steps to create a database, make collections, and store documents. Per altre informazioni sui comandi della shell mongo, vedere Working with the mongo Shell (Utilizzo della shell mongo).For more information on mongo Shell commands, see Working with the mongo Shell.

  1. Scegliere una directory nel computer di sviluppo per archiviare i dati.Choose a directory on your development machine for storing the data. Ad esempio, C: \ BooksData in Windows.For example, C:\BooksData on Windows. Creare la directory se non esiste.Create the directory if it doesn't exist. La shell mongo non consente di creare nuove directory.The mongo Shell doesn't create new directories.

  2. Aprire una shell dei comandi.Open a command shell. Eseguire il comando seguente per connettersi a MongoDB sulla porta predefinita 27017.Run the following command to connect to MongoDB on default port 27017. Ricordare di sostituire <data_directory_path> con la directory scelta nel passaggio precedente.Remember to replace <data_directory_path> with the directory you chose in the previous step.

    mongod --dbpath <data_directory_path>
    
  3. Aprire un'altra istanza della shell dei comandi.Open another command shell instance. Connettersi al database di test predefinito eseguendo il comando seguente:Connect to the default test database by running the following command:

    mongo
    
  4. Eseguire il comando seguente in una shell dei comandi:Run the following in a command shell:

    use BookstoreDb
    

    Se non esiste già, viene creato un database denominato BookstoreDb.If it doesn't already exist, a database named BookstoreDb is created. Se il database esiste, la connessione viene aperta per le transazioni.If the database does exist, its connection is opened for transactions.

  5. Creare una raccolta Books tramite il comando seguente:Create a Books collection using following command:

    db.createCollection('Books')
    

    Viene visualizzato il risultato seguente:The following result is displayed:

    { "ok" : 1 }
    
  6. Definire uno schema per la raccolta Books e inserire due documenti usando il comando seguente:Define a schema for the Books collection and insert two documents using the following command:

    db.Books.insertMany([{'Name':'Design Patterns','Price':54.93,'Category':'Computers','Author':'Ralph Johnson'}, {'Name':'Clean Code','Price':43.15,'Category':'Computers','Author':'Robert C. Martin'}])
    

    Viene visualizzato il risultato seguente:The following result is displayed:

    {
      "acknowledged" : true,
      "insertedIds" : [
        ObjectId("5bfd996f7b8e48dc15ff215d"),
        ObjectId("5bfd996f7b8e48dc15ff215e")
      ]
    }
    

    Nota

    L'ID illustrato in questo articolo non corrisponde agli ID quando si esegue questo campione.The ID's shown in this article will not match the IDs when you run this sample.

  7. Visualizzare i documenti nel database usando il comando seguente:View the documents in the database using the following command:

    db.Books.find({}).pretty()
    

    Viene visualizzato il risultato seguente:The following result is displayed:

    {
      "_id" : ObjectId("5bfd996f7b8e48dc15ff215d"),
      "Name" : "Design Patterns",
      "Price" : 54.93,
      "Category" : "Computers",
      "Author" : "Ralph Johnson"
    }
    {
      "_id" : ObjectId("5bfd996f7b8e48dc15ff215e"),
      "Name" : "Clean Code",
      "Price" : 43.15,
      "Category" : "Computers",
      "Author" : "Robert C. Martin"
    }
    

    Lo schema aggiunge una proprietà _id generata automaticamente di tipo ObjectId per ogni documento.The schema adds an autogenerated _id property of type ObjectId for each document.

Il database è pronto.The database is ready. È possibile iniziare a creare l'API Web ASP.NET Core.You can start creating the ASP.NET Core web API.

Creare il progetto per l'API Web ASP.NET CoreCreate the ASP.NET Core web API project

  1. Passare a file > nuovo > progetto.Go to File > New > Project.

  2. Selezionare il tipo di progetto Applicazione Web ASP.NET Core e selezionare Avanti.Select the ASP.NET Core Web Application project type, and select Next.

  3. Assegnare al progetto il nome BooksApi e selezionare Crea.Name the project BooksApi, and select Create.

  4. Selezionare il framework di destinazione .NET Core e ASP.NET Core 3.0.Select the .NET Core target framework and ASP.NET Core 3.0. Selezionare il modello di progetto API e scegliere Crea.Select the API project template, and select Create.

  5. Visitare la raccolta NuGet: MongoDB. driver per determinare la versione stabile più recente del driver .NET per MongoDB.Visit the NuGet Gallery: MongoDB.Driver to determine the latest stable version of the .NET driver for MongoDB. Nella finestra Console di Gestione pacchetti passare alla radice del progetto.In the Package Manager Console window, navigate to the project root. Eseguire il comando seguente per installare il driver .NET per MongoDB:Run the following command to install the .NET driver for MongoDB:

    Install-Package MongoDB.Driver -Version {VERSION}
    

Aggiungere un modello di entitàAdd an entity model

  1. Aggiungere una directory Models alla radice del progetto.Add a Models directory to the project root.

  2. Aggiungere una classe Book alla directory Models con il codice seguente:Add a Book class to the Models directory with the following code:

    using MongoDB.Bson;
    using MongoDB.Bson.Serialization.Attributes;
    
    namespace BooksApi.Models
    {
        public class Book
        {
            [BsonId]
            [BsonRepresentation(BsonType.ObjectId)]
            public string Id { get; set; }
    
            [BsonElement("Name")]
            public string BookName { get; set; }
    
            public decimal Price { get; set; }
    
            public string Category { get; set; }
    
            public string Author { get; set; }
        }
    }
    

    Nella classe precedente, la proprietà Id:In the preceding class, the Id property:

    • È obbligatoria per il mapping tra l'oggetto CLR (Common Language Runtime) e la raccolta MongoDB.Is required for mapping the Common Language Runtime (CLR) object to the MongoDB collection.
    • Viene annotato con [BsonId] per indicare questa proprietà come chiave primaria del documento.Is annotated with [BsonId] to designate this property as the document's primary key.
    • Viene annotato con [BsonRepresentation(BsonType.ObjectId)] per consentire il passaggio del parametro come tipo string anziché come una struttura ObjectID .Is annotated with [BsonRepresentation(BsonType.ObjectId)] to allow passing the parameter as type string instead of an ObjectId structure. Mongo gestisce la conversione da string a ObjectId.Mongo handles the conversion from string to ObjectId.

    La BookName proprietà è annotata con l' [BsonElement] attributo.The BookName property is annotated with the [BsonElement] attribute. Il valore dell'attributo Name rappresenta il nome della proprietà nella raccolta MongoDB.The attribute's value of Name represents the property name in the MongoDB collection.

Aggiungere un modello di configurazioneAdd a configuration model

  1. Aggiungere i seguenti valori di configurazione del database a appsettings.json:Add the following database configuration values to appsettings.json:

    {
      "BookstoreDatabaseSettings": {
        "BooksCollectionName": "Books",
        "ConnectionString": "mongodb://localhost:27017",
        "DatabaseName": "BookstoreDb"
      },
      "Logging": {
        "IncludeScopes": false,
        "Debug": {
          "LogLevel": {
            "Default": "Warning"
          }
        },
        "Console": {
          "LogLevel": {
            "Default": "Warning"
          }
        }
      }
    }
    
  2. Aggiungere un file BookstoreDatabaseSettings.cs alla directory Models con il codice seguente:Add a BookstoreDatabaseSettings.cs file to the Models directory with the following code:

    namespace BooksApi.Models
    {
        public class BookstoreDatabaseSettings : IBookstoreDatabaseSettings
        {
            public string BooksCollectionName { get; set; }
            public string ConnectionString { get; set; }
            public string DatabaseName { get; set; }
        }
    
        public interface IBookstoreDatabaseSettings
        {
            string BooksCollectionName { get; set; }
            string ConnectionString { get; set; }
            string DatabaseName { get; set; }
        }
    }
    

    La classe BookstoreDatabaseSettings precedente viene utilizzata per archiviare i valori della proprietà BookstoreDatabaseSettings del file appsettings.json.The preceding BookstoreDatabaseSettings class is used to store the appsettings.json file's BookstoreDatabaseSettings property values. I nomi delle proprietà JSON e C# sono identici per semplificare il processo di mapping.The JSON and C# property names are named identically to ease the mapping process.

  3. Aggiungere il codice evidenziato seguente a Startup.ConfigureServices:Add the following highlighted code to Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        // requires using Microsoft.Extensions.Options
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddControllers();
    }
    

    Nel codice precedente:In the preceding code:

    • L'istanza di configurazione a cui si associa la sezione BookstoreDatabaseSettings del file appsettings.json viene registrata nel contenitore di inserimento delle dipendenze.The configuration instance to which the appsettings.json file's BookstoreDatabaseSettings section binds is registered in the Dependency Injection (DI) container. Una proprietà ConnectionString di un oggetto BookstoreDatabaseSettings viene popolata con la proprietà BookstoreDatabaseSettings:ConnectionString in appsettings.json.For example, a BookstoreDatabaseSettings object's ConnectionString property is populated with the BookstoreDatabaseSettings:ConnectionString property in appsettings.json.
    • L'interfaccia IBookstoreDatabaseSettings è registrata nell'inserimento di dipendenze con una durata del servizio singleton.The IBookstoreDatabaseSettings interface is registered in DI with a singleton service lifetime. Quando avviene l'inserimento, l'istanza dell'interfaccia restituisce un oggetto BookstoreDatabaseSettings.When injected, the interface instance resolves to a BookstoreDatabaseSettings object.
  4. Aggiungere il codice seguente all'inizio del file Startup.cs per risolvere i riferimenti a BookstoreDatabaseSettings e IBookstoreDatabaseSettings:Add the following code to the top of Startup.cs to resolve the BookstoreDatabaseSettings and IBookstoreDatabaseSettings references:

    using BooksApi.Models;
    

Aggiungere un servizio di operazioni CRUDAdd a CRUD operations service

  1. Aggiungere una directory Services alla radice del progetto.Add a Services directory to the project root.

  2. Aggiungere una classe BookService alla directory Services con il codice seguente:Add a BookService class to the Services directory with the following code:

    using BooksApi.Models;
    using MongoDB.Driver;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace BooksApi.Services
    {
        public class BookService
        {
            private readonly IMongoCollection<Book> _books;
    
            public BookService(IBookstoreDatabaseSettings settings)
            {
                var client = new MongoClient(settings.ConnectionString);
                var database = client.GetDatabase(settings.DatabaseName);
    
                _books = database.GetCollection<Book>(settings.BooksCollectionName);
            }
    
            public List<Book> Get() =>
                _books.Find(book => true).ToList();
    
            public Book Get(string id) =>
                _books.Find<Book>(book => book.Id == id).FirstOrDefault();
    
            public Book Create(Book book)
            {
                _books.InsertOne(book);
                return book;
            }
    
            public void Update(string id, Book bookIn) =>
                _books.ReplaceOne(book => book.Id == id, bookIn);
    
            public void Remove(Book bookIn) =>
                _books.DeleteOne(book => book.Id == bookIn.Id);
    
            public void Remove(string id) => 
                _books.DeleteOne(book => book.Id == id);
        }
    }
    

    Nel codice precedente un'istanza di IBookstoreDatabaseSettings viene recuperata dall'inserimento di dipendenze tramite l'inserimento del costruttore.In the preceding code, an IBookstoreDatabaseSettings instance is retrieved from DI via constructor injection. Questa tecnica fornisce accesso ai valori di configurazione di appsettings.json che sono stati aggiunti nella sezione Aggiungere un modello di configurazione.This technique provides access to the appsettings.json configuration values that were added in the Add a configuration model section.

  3. Aggiungere il codice evidenziato seguente a Startup.ConfigureServices:Add the following highlighted code to Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddSingleton<BookService>();
    
        services.AddControllers();
    }
    

    Nel codice precedente la classe BookService è registrata con l'inserimento di dipendenze per supportare l'inserimento del costruttore nelle classi che la utilizzano.In the preceding code, the BookService class is registered with DI to support constructor injection in consuming classes. La durata del servizio singleton è più appropriata perché BookService assume una dipendenza diretta a MongoClient.The singleton service lifetime is most appropriate because BookService takes a direct dependency on MongoClient. Le linee guida per il riutilizzo dei client mongoufficiali MongoClient devono essere registrate in di con una durata del servizio singleton.Per the official Mongo Client reuse guidelines, MongoClient should be registered in DI with a singleton service lifetime.

  4. Aggiungere il codice seguente all'inizio del file Startup.cs per risolvere il riferimento a BookService:Add the following code to the top of Startup.cs to resolve the BookService reference:

    using BooksApi.Services;
    

La classe BookService usa i membri MongoDB.Driver seguenti per eseguire operazioni CRUD sul database:The BookService class uses the following MongoDB.Driver members to perform CRUD operations against the database:

  • MongoClient: legge l'istanza del server per l'esecuzione di operazioni di database.MongoClient: Reads the server instance for performing database operations. Al costruttore di questa classe viene passata la stringa di connessione MongoDB:The constructor of this class is provided the MongoDB connection string:

    public BookService(IBookstoreDatabaseSettings settings)
    {
        var client = new MongoClient(settings.ConnectionString);
        var database = client.GetDatabase(settings.DatabaseName);
    
        _books = database.GetCollection<Book>(settings.BooksCollectionName);
    }
    
  • IMongoDatabase: rappresenta il database Mongo per l'esecuzione di operazioni.IMongoDatabase: Represents the Mongo database for performing operations. Questa esercitazione usa il metodo GetCollection<TDocument>(collection) generico sull'interfaccia per ottenere l'accesso ai dati in una raccolta specifica.This tutorial uses the generic GetCollection<TDocument>(collection) method on the interface to gain access to data in a specific collection. Eseguire le operazioni CRUD sulla raccolta dopo la chiamata a questo metodo.Perform CRUD operations against the collection after this method is called. Nella chiamata del metodo GetCollection<TDocument>(collection):In the GetCollection<TDocument>(collection) method call:

    • collection rappresenta il nome della raccolta.collection represents the collection name.
    • TDocument rappresenta il tipo di oggetto CLR archiviato nella raccolta.TDocument represents the CLR object type stored in the collection.

GetCollection<TDocument>(collection) restituisce un oggetto MongoCollection che rappresenta la raccolta.GetCollection<TDocument>(collection) returns a MongoCollection object representing the collection. In questa esercitazione, vengono richiamati i metodi seguenti sulla raccolta:In this tutorial, the following methods are invoked on the collection:

  • DeleteOne: Elimina un singolo documento corrispondente ai criteri di ricerca specificati.DeleteOne: Deletes a single document matching the provided search criteria.
  • Find <TDocument> : restituisce tutti i documenti nella raccolta che corrispondono ai criteri di ricerca specificati.Find<TDocument>: Returns all documents in the collection matching the provided search criteria.
  • InsertOne: inserisce l'oggetto fornito come nuovo documento nella raccolta.InsertOne: Inserts the provided object as a new document in the collection.
  • ReplaceOne: sostituisce il singolo documento corrispondente ai criteri di ricerca specificati con l'oggetto fornito.ReplaceOne: Replaces the single document matching the provided search criteria with the provided object.

Aggiunta di un controllerAdd a controller

Aggiungere una classe BooksController alla directory Controllers con il codice seguente:Add a BooksController class to the Controllers directory with the following code:

using BooksApi.Models;
using BooksApi.Services;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace BooksApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BooksController : ControllerBase
    {
        private readonly BookService _bookService;

        public BooksController(BookService bookService)
        {
            _bookService = bookService;
        }

        [HttpGet]
        public ActionResult<List<Book>> Get() =>
            _bookService.Get();

        [HttpGet("{id:length(24)}", Name = "GetBook")]
        public ActionResult<Book> Get(string id)
        {
            var book = _bookService.Get(id);

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

            return book;
        }

        [HttpPost]
        public ActionResult<Book> Create(Book book)
        {
            _bookService.Create(book);

            return CreatedAtRoute("GetBook", new { id = book.Id.ToString() }, book);
        }

        [HttpPut("{id:length(24)}")]
        public IActionResult Update(string id, Book bookIn)
        {
            var book = _bookService.Get(id);

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

            _bookService.Update(id, bookIn);

            return NoContent();
        }

        [HttpDelete("{id:length(24)}")]
        public IActionResult Delete(string id)
        {
            var book = _bookService.Get(id);

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

            _bookService.Remove(book.Id);

            return NoContent();
        }
    }
}

Il controller dell'API Web precedente:The preceding web API controller:

  • Usa la classe BookService per eseguire operazioni CRUD.Uses the BookService class to perform CRUD operations.
  • Contiene metodi di azione per supportare le richieste HTTP GET, POST, PUT e DELETE.Contains action methods to support GET, POST, PUT, and DELETE HTTP requests.
  • Chiama CreatedAtRoute nel metodo dell'azione Create per restituire una risposta HTTP 201.Calls CreatedAtRoute in the Create action method to return an HTTP 201 response. Il codice di stato 201 è la risposta standard per un metodo HTTP POST che crea una nuova risorsa nel server.Status code 201 is the standard response for an HTTP POST method that creates a new resource on the server. Location aggiunge anche un'intestazione CreatedAtRoute alla risposta.CreatedAtRoute also adds a Location header to the response. L'intestazione Location specifica l'URI del libro appena creato.The Location header specifies the URI of the newly created book.

Testare l'API WebTest the web API

  1. Compila ed esegui l'app.Build and run the app.

  2. Passare a http://localhost:<port>/api/books per testare il metodo dell'azione Get senza parametri del controller.Navigate to http://localhost:<port>/api/books to test the controller's parameterless Get action method. Viene visualizzata la risposta JSON seguente:The following JSON response is displayed:

    [
      {
        "id":"5bfd996f7b8e48dc15ff215d",
        "bookName":"Design Patterns",
        "price":54.93,
        "category":"Computers",
        "author":"Ralph Johnson"
      },
      {
        "id":"5bfd996f7b8e48dc15ff215e",
        "bookName":"Clean Code",
        "price":43.15,
        "category":"Computers",
        "author":"Robert C. Martin"
      }
    ]
    
  3. Passare a http://localhost:<port>/api/books/{id here} per testare il metodo dell'azione Get in overload del controller.Navigate to http://localhost:<port>/api/books/{id here} to test the controller's overloaded Get action method. Viene visualizzata la risposta JSON seguente:The following JSON response is displayed:

    {
      "id":"{ID}",
      "bookName":"Clean Code",
      "price":43.15,
      "category":"Computers",
      "author":"Robert C. Martin"
    }
    

Configurare le opzioni di serializzazione JSONConfigure JSON serialization options

Esistono due dettagli da modificare per le risposte JSON restituite nella sezione Testare l'API Web:There are two details to change about the JSON responses returned in the Test the web API section:

  • La notazione a cammello predefinita per i nomi di proprietà deve essere modificata in modo da adottare la convenzione Pascal dei nomi di proprietà dell'oggetto CLR.The property names' default camel casing should be changed to match the Pascal casing of the CLR object's property names.
  • La proprietà bookName deve essere restituita come Name.The bookName property should be returned as Name.

Per soddisfare i requisiti precedenti, apportare le modifiche seguenti:To satisfy the preceding requirements, make the following changes:

  1. JSON.NET è stato rimosso dal framework condiviso di ASP.NET.JSON.NET has been removed from ASP.NET shared framework. Aggiungere un riferimento al pacchetto a Microsoft.AspNetCore.Mvc.NewtonsoftJson .Add a package reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson.

  2. In Startup.ConfigureServices concatenare il codice evidenziato seguente alla chiamata del metodo AddControllers:In Startup.ConfigureServices, chain the following highlighted code on to the AddControllers method call:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddSingleton<BookService>();
    
        services.AddControllers()
            .AddNewtonsoftJson(options => options.UseMemberCasing());
    }
    

    Con la modifica precedente, i nomi delle proprietà nella risposta JSON serializzata dell'API Web corrispondono ai nomi di proprietà corrispondenti nel tipo di oggetto CLR.With the preceding change, property names in the web API's serialized JSON response match their corresponding property names in the CLR object type. Ad esempio, la proprietà Author della classe Book viene serializzata come Author.For example, the Book class's Author property serializes as Author.

  3. In models/book. csannotare la BookName proprietà con l' [JsonProperty] attributo seguente:In Models/Book.cs, annotate the BookName property with the following [JsonProperty] attribute:

    [BsonElement("Name")]
    [JsonProperty("Name")]
    public string BookName { get; set; }
    

    Il valore Name dell'attributo [JsonProperty] rappresenta il nome della proprietà nella risposta JSON serializzata dell'API Web.The [JsonProperty] attribute's value of Name represents the property name in the web API's serialized JSON response.

  4. Aggiungere il codice seguente all'inizio di Models/Book.cs per risolvere il riferimento all'attributo [JsonProperty]:Add the following code to the top of Models/Book.cs to resolve the [JsonProperty] attribute reference:

    using Newtonsoft.Json;
    
  5. Ripetere i passaggi definiti nella sezione Testare l'API Web.Repeat the steps defined in the Test the web API section. Si noti la differenza nei nomi di proprietà JSON.Notice the difference in JSON property names.

Questa esercitazione crea un'API Web che esegue operazioni di creazione, lettura, aggiornamento ed eliminazione (CRUD) su un database NoSQL MongoDB.This tutorial creates a web API that performs Create, Read, Update, and Delete (CRUD) operations on a MongoDB NoSQL database.

In questa esercitazione verranno illustrate le procedure per:In this tutorial, you learn how to:

  • Configurare MongoDBConfigure MongoDB
  • Creare un database MongoDBCreate a MongoDB database
  • Definire una raccolta e uno schema MongoDBDefine a MongoDB collection and schema
  • Eseguire operazioni CRUD di MongoDB da un'API WebPerform MongoDB CRUD operations from a web API
  • Personalizzare la serializzazione JSONCustomize JSON serialization

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

PrerequisitiPrerequisites

Configurare MongoDBConfigure MongoDB

Se si usa Windows, MongoDB viene installato in C: \ programmi \ MongoDB per impostazione predefinita.If using Windows, MongoDB is installed at C:\Program Files\MongoDB by default. Aggiungere C: \ Program Files \ MongoDB \ server \ <version_number> \ bin alla Path variabile di ambiente.Add C:\Program Files\MongoDB\Server\<version_number>\bin to the Path environment variable. Questa modifica consente l'accesso MongoDB da qualsiasi posizione nel computer di sviluppo.This change enables MongoDB access from anywhere on your development machine.

Usare la shell mongo nelle procedure seguenti per creare un database, creare le raccolte e archiviare i documenti.Use the mongo Shell in the following steps to create a database, make collections, and store documents. Per altre informazioni sui comandi della shell mongo, vedere Working with the mongo Shell (Utilizzo della shell mongo).For more information on mongo Shell commands, see Working with the mongo Shell.

  1. Scegliere una directory nel computer di sviluppo per archiviare i dati.Choose a directory on your development machine for storing the data. Ad esempio, C: \ BooksData in Windows.For example, C:\BooksData on Windows. Creare la directory se non esiste.Create the directory if it doesn't exist. La shell mongo non consente di creare nuove directory.The mongo Shell doesn't create new directories.

  2. Aprire una shell dei comandi.Open a command shell. Eseguire il comando seguente per connettersi a MongoDB sulla porta predefinita 27017.Run the following command to connect to MongoDB on default port 27017. Ricordare di sostituire <data_directory_path> con la directory scelta nel passaggio precedente.Remember to replace <data_directory_path> with the directory you chose in the previous step.

    mongod --dbpath <data_directory_path>
    
  3. Aprire un'altra istanza della shell dei comandi.Open another command shell instance. Connettersi al database di test predefinito eseguendo il comando seguente:Connect to the default test database by running the following command:

    mongo
    
  4. Eseguire il comando seguente in una shell dei comandi:Run the following in a command shell:

    use BookstoreDb
    

    Se non esiste già, viene creato un database denominato BookstoreDb.If it doesn't already exist, a database named BookstoreDb is created. Se il database esiste, la connessione viene aperta per le transazioni.If the database does exist, its connection is opened for transactions.

  5. Creare una raccolta Books tramite il comando seguente:Create a Books collection using following command:

    db.createCollection('Books')
    

    Viene visualizzato il risultato seguente:The following result is displayed:

    { "ok" : 1 }
    
  6. Definire uno schema per la raccolta Books e inserire due documenti usando il comando seguente:Define a schema for the Books collection and insert two documents using the following command:

    db.Books.insertMany([{'Name':'Design Patterns','Price':54.93,'Category':'Computers','Author':'Ralph Johnson'}, {'Name':'Clean Code','Price':43.15,'Category':'Computers','Author':'Robert C. Martin'}])
    

    Viene visualizzato il risultato seguente:The following result is displayed:

    {
      "acknowledged" : true,
      "insertedIds" : [
        ObjectId("5bfd996f7b8e48dc15ff215d"),
        ObjectId("5bfd996f7b8e48dc15ff215e")
      ]
    }
    

    Nota

    L'ID illustrato in questo articolo non corrisponde agli ID quando si esegue questo campione.The ID's shown in this article will not match the IDs when you run this sample.

  7. Visualizzare i documenti nel database usando il comando seguente:View the documents in the database using the following command:

    db.Books.find({}).pretty()
    

    Viene visualizzato il risultato seguente:The following result is displayed:

    {
      "_id" : ObjectId("5bfd996f7b8e48dc15ff215d"),
      "Name" : "Design Patterns",
      "Price" : 54.93,
      "Category" : "Computers",
      "Author" : "Ralph Johnson"
    }
    {
      "_id" : ObjectId("5bfd996f7b8e48dc15ff215e"),
      "Name" : "Clean Code",
      "Price" : 43.15,
      "Category" : "Computers",
      "Author" : "Robert C. Martin"
    }
    

    Lo schema aggiunge una proprietà _id generata automaticamente di tipo ObjectId per ogni documento.The schema adds an autogenerated _id property of type ObjectId for each document.

Il database è pronto.The database is ready. È possibile iniziare a creare l'API Web ASP.NET Core.You can start creating the ASP.NET Core web API.

Creare il progetto per l'API Web ASP.NET CoreCreate the ASP.NET Core web API project

  1. Passare a file > nuovo > progetto.Go to File > New > Project.

  2. Selezionare il tipo di progetto Applicazione Web ASP.NET Core e selezionare Avanti.Select the ASP.NET Core Web Application project type, and select Next.

  3. Assegnare al progetto il nome BooksApi e selezionare Crea.Name the project BooksApi, and select Create.

  4. Selezionare il framework di destinazione .NET Core e ASP.NET Core 2.2.Select the .NET Core target framework and ASP.NET Core 2.2. Selezionare il modello di progetto API e scegliere Crea.Select the API project template, and select Create.

  5. Visitare la raccolta NuGet: MongoDB. driver per determinare la versione stabile più recente del driver .NET per MongoDB.Visit the NuGet Gallery: MongoDB.Driver to determine the latest stable version of the .NET driver for MongoDB. Nella finestra Console di Gestione pacchetti passare alla radice del progetto.In the Package Manager Console window, navigate to the project root. Eseguire il comando seguente per installare il driver .NET per MongoDB:Run the following command to install the .NET driver for MongoDB:

    Install-Package MongoDB.Driver -Version {VERSION}
    

Aggiungere un modello di entitàAdd an entity model

  1. Aggiungere una directory Models alla radice del progetto.Add a Models directory to the project root.

  2. Aggiungere una classe Book alla directory Models con il codice seguente:Add a Book class to the Models directory with the following code:

    using MongoDB.Bson;
    using MongoDB.Bson.Serialization.Attributes;
    
    namespace BooksApi.Models
    {
        public class Book
        {
            [BsonId]
            [BsonRepresentation(BsonType.ObjectId)]
            public string Id { get; set; }
    
            [BsonElement("Name")]
            public string BookName { get; set; }
    
            public decimal Price { get; set; }
    
            public string Category { get; set; }
    
            public string Author { get; set; }
        }
    }
    

    Nella classe precedente, la proprietà Id:In the preceding class, the Id property:

    • È obbligatoria per il mapping tra l'oggetto CLR (Common Language Runtime) e la raccolta MongoDB.Is required for mapping the Common Language Runtime (CLR) object to the MongoDB collection.
    • Viene annotato con [BsonId] per indicare questa proprietà come chiave primaria del documento.Is annotated with [BsonId] to designate this property as the document's primary key.
    • Viene annotato con [BsonRepresentation(BsonType.ObjectId)] per consentire il passaggio del parametro come tipo string anziché come una struttura ObjectID .Is annotated with [BsonRepresentation(BsonType.ObjectId)] to allow passing the parameter as type string instead of an ObjectId structure. Mongo gestisce la conversione da string a ObjectId.Mongo handles the conversion from string to ObjectId.

    La BookName proprietà è annotata con l' [BsonElement] attributo.The BookName property is annotated with the [BsonElement] attribute. Il valore dell'attributo Name rappresenta il nome della proprietà nella raccolta MongoDB.The attribute's value of Name represents the property name in the MongoDB collection.

Aggiungere un modello di configurazioneAdd a configuration model

  1. Aggiungere i seguenti valori di configurazione del database a appsettings.json:Add the following database configuration values to appsettings.json:

    {
      "BookstoreDatabaseSettings": {
        "BooksCollectionName": "Books",
        "ConnectionString": "mongodb://localhost:27017",
        "DatabaseName": "BookstoreDb"
      },
      "Logging": {
        "IncludeScopes": false,
        "Debug": {
          "LogLevel": {
            "Default": "Warning"
          }
        },
        "Console": {
          "LogLevel": {
            "Default": "Warning"
          }
        }
      }
    }
    
  2. Aggiungere un file BookstoreDatabaseSettings.cs alla directory Models con il codice seguente:Add a BookstoreDatabaseSettings.cs file to the Models directory with the following code:

    namespace BooksApi.Models
    {
        public class BookstoreDatabaseSettings : IBookstoreDatabaseSettings
        {
            public string BooksCollectionName { get; set; }
            public string ConnectionString { get; set; }
            public string DatabaseName { get; set; }
        }
    
        public interface IBookstoreDatabaseSettings
        {
            string BooksCollectionName { get; set; }
            string ConnectionString { get; set; }
            string DatabaseName { get; set; }
        }
    }
    

    La classe BookstoreDatabaseSettings precedente viene utilizzata per archiviare i valori della proprietà BookstoreDatabaseSettings del file appsettings.json.The preceding BookstoreDatabaseSettings class is used to store the appsettings.json file's BookstoreDatabaseSettings property values. I nomi delle proprietà JSON e C# sono identici per semplificare il processo di mapping.The JSON and C# property names are named identically to ease the mapping process.

  3. Aggiungere il codice evidenziato seguente a Startup.ConfigureServices:Add the following highlighted code to Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }
    

    Nel codice precedente:In the preceding code:

    • L'istanza di configurazione a cui si associa la sezione BookstoreDatabaseSettings del file appsettings.json viene registrata nel contenitore di inserimento delle dipendenze.The configuration instance to which the appsettings.json file's BookstoreDatabaseSettings section binds is registered in the Dependency Injection (DI) container. Una proprietà ConnectionString di un oggetto BookstoreDatabaseSettings viene popolata con la proprietà BookstoreDatabaseSettings:ConnectionString in appsettings.json.For example, a BookstoreDatabaseSettings object's ConnectionString property is populated with the BookstoreDatabaseSettings:ConnectionString property in appsettings.json.
    • L'interfaccia IBookstoreDatabaseSettings è registrata nell'inserimento di dipendenze con una durata del servizio singleton.The IBookstoreDatabaseSettings interface is registered in DI with a singleton service lifetime. Quando avviene l'inserimento, l'istanza dell'interfaccia restituisce un oggetto BookstoreDatabaseSettings.When injected, the interface instance resolves to a BookstoreDatabaseSettings object.
  4. Aggiungere il codice seguente all'inizio del file Startup.cs per risolvere i riferimenti a BookstoreDatabaseSettings e IBookstoreDatabaseSettings:Add the following code to the top of Startup.cs to resolve the BookstoreDatabaseSettings and IBookstoreDatabaseSettings references:

    using BooksApi.Models;
    

Aggiungere un servizio di operazioni CRUDAdd a CRUD operations service

  1. Aggiungere una directory Services alla radice del progetto.Add a Services directory to the project root.

  2. Aggiungere una classe BookService alla directory Services con il codice seguente:Add a BookService class to the Services directory with the following code:

    using BooksApi.Models;
    using MongoDB.Driver;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace BooksApi.Services
    {
        public class BookService
        {
            private readonly IMongoCollection<Book> _books;
    
            public BookService(IBookstoreDatabaseSettings settings)
            {
                var client = new MongoClient(settings.ConnectionString);
                var database = client.GetDatabase(settings.DatabaseName);
    
                _books = database.GetCollection<Book>(settings.BooksCollectionName);
            }
    
            public List<Book> Get() =>
                _books.Find(book => true).ToList();
    
            public Book Get(string id) =>
                _books.Find<Book>(book => book.Id == id).FirstOrDefault();
    
            public Book Create(Book book)
            {
                _books.InsertOne(book);
                return book;
            }
    
            public void Update(string id, Book bookIn) =>
                _books.ReplaceOne(book => book.Id == id, bookIn);
    
            public void Remove(Book bookIn) =>
                _books.DeleteOne(book => book.Id == bookIn.Id);
    
            public void Remove(string id) => 
                _books.DeleteOne(book => book.Id == id);
        }
    }
    

    Nel codice precedente un'istanza di IBookstoreDatabaseSettings viene recuperata dall'inserimento di dipendenze tramite l'inserimento del costruttore.In the preceding code, an IBookstoreDatabaseSettings instance is retrieved from DI via constructor injection. Questa tecnica fornisce accesso ai valori di configurazione di appsettings.json che sono stati aggiunti nella sezione Aggiungere un modello di configurazione.This technique provides access to the appsettings.json configuration values that were added in the Add a configuration model section.

  3. Aggiungere il codice evidenziato seguente a Startup.ConfigureServices:Add the following highlighted code to Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddSingleton<BookService>();
    
        services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }
    

    Nel codice precedente la classe BookService è registrata con l'inserimento di dipendenze per supportare l'inserimento del costruttore nelle classi che la utilizzano.In the preceding code, the BookService class is registered with DI to support constructor injection in consuming classes. La durata del servizio singleton è più appropriata perché BookService assume una dipendenza diretta a MongoClient.The singleton service lifetime is most appropriate because BookService takes a direct dependency on MongoClient. Le linee guida per il riutilizzo dei client mongoufficiali MongoClient devono essere registrate in di con una durata del servizio singleton.Per the official Mongo Client reuse guidelines, MongoClient should be registered in DI with a singleton service lifetime.

  4. Aggiungere il codice seguente all'inizio del file Startup.cs per risolvere il riferimento a BookService:Add the following code to the top of Startup.cs to resolve the BookService reference:

    using BooksApi.Services;
    

La classe BookService usa i membri MongoDB.Driver seguenti per eseguire operazioni CRUD sul database:The BookService class uses the following MongoDB.Driver members to perform CRUD operations against the database:

  • MongoClient: legge l'istanza del server per l'esecuzione di operazioni di database.MongoClient: Reads the server instance for performing database operations. Al costruttore di questa classe viene passata la stringa di connessione MongoDB:The constructor of this class is provided the MongoDB connection string:

    public BookService(IBookstoreDatabaseSettings settings)
    {
        var client = new MongoClient(settings.ConnectionString);
        var database = client.GetDatabase(settings.DatabaseName);
    
        _books = database.GetCollection<Book>(settings.BooksCollectionName);
    }
    
  • IMongoDatabase: rappresenta il database Mongo per l'esecuzione di operazioni.IMongoDatabase: Represents the Mongo database for performing operations. Questa esercitazione usa il metodo GetCollection<TDocument>(collection) generico sull'interfaccia per ottenere l'accesso ai dati in una raccolta specifica.This tutorial uses the generic GetCollection<TDocument>(collection) method on the interface to gain access to data in a specific collection. Eseguire le operazioni CRUD sulla raccolta dopo la chiamata a questo metodo.Perform CRUD operations against the collection after this method is called. Nella chiamata del metodo GetCollection<TDocument>(collection):In the GetCollection<TDocument>(collection) method call:

    • collection rappresenta il nome della raccolta.collection represents the collection name.
    • TDocument rappresenta il tipo di oggetto CLR archiviato nella raccolta.TDocument represents the CLR object type stored in the collection.

GetCollection<TDocument>(collection) restituisce un oggetto MongoCollection che rappresenta la raccolta.GetCollection<TDocument>(collection) returns a MongoCollection object representing the collection. In questa esercitazione, vengono richiamati i metodi seguenti sulla raccolta:In this tutorial, the following methods are invoked on the collection:

  • DeleteOne: Elimina un singolo documento corrispondente ai criteri di ricerca specificati.DeleteOne: Deletes a single document matching the provided search criteria.
  • Find <TDocument> : restituisce tutti i documenti nella raccolta che corrispondono ai criteri di ricerca specificati.Find<TDocument>: Returns all documents in the collection matching the provided search criteria.
  • InsertOne: inserisce l'oggetto fornito come nuovo documento nella raccolta.InsertOne: Inserts the provided object as a new document in the collection.
  • ReplaceOne: sostituisce il singolo documento corrispondente ai criteri di ricerca specificati con l'oggetto fornito.ReplaceOne: Replaces the single document matching the provided search criteria with the provided object.

Aggiunta di un controllerAdd a controller

Aggiungere una classe BooksController alla directory Controllers con il codice seguente:Add a BooksController class to the Controllers directory with the following code:

using BooksApi.Models;
using BooksApi.Services;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace BooksApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BooksController : ControllerBase
    {
        private readonly BookService _bookService;

        public BooksController(BookService bookService)
        {
            _bookService = bookService;
        }

        [HttpGet]
        public ActionResult<List<Book>> Get() =>
            _bookService.Get();

        [HttpGet("{id:length(24)}", Name = "GetBook")]
        public ActionResult<Book> Get(string id)
        {
            var book = _bookService.Get(id);

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

            return book;
        }

        [HttpPost]
        public ActionResult<Book> Create(Book book)
        {
            _bookService.Create(book);

            return CreatedAtRoute("GetBook", new { id = book.Id.ToString() }, book);
        }

        [HttpPut("{id:length(24)}")]
        public IActionResult Update(string id, Book bookIn)
        {
            var book = _bookService.Get(id);

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

            _bookService.Update(id, bookIn);

            return NoContent();
        }

        [HttpDelete("{id:length(24)}")]
        public IActionResult Delete(string id)
        {
            var book = _bookService.Get(id);

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

            _bookService.Remove(book.Id);

            return NoContent();
        }
    }
}

Il controller dell'API Web precedente:The preceding web API controller:

  • Usa la classe BookService per eseguire operazioni CRUD.Uses the BookService class to perform CRUD operations.
  • Contiene metodi di azione per supportare le richieste HTTP GET, POST, PUT e DELETE.Contains action methods to support GET, POST, PUT, and DELETE HTTP requests.
  • Chiama CreatedAtRoute nel metodo dell'azione Create per restituire una risposta HTTP 201.Calls CreatedAtRoute in the Create action method to return an HTTP 201 response. Il codice di stato 201 è la risposta standard per un metodo HTTP POST che crea una nuova risorsa nel server.Status code 201 is the standard response for an HTTP POST method that creates a new resource on the server. Location aggiunge anche un'intestazione CreatedAtRoute alla risposta.CreatedAtRoute also adds a Location header to the response. L'intestazione Location specifica l'URI del libro appena creato.The Location header specifies the URI of the newly created book.

Testare l'API WebTest the web API

  1. Compila ed esegui l'app.Build and run the app.

  2. Passare a http://localhost:<port>/api/books per testare il metodo dell'azione Get senza parametri del controller.Navigate to http://localhost:<port>/api/books to test the controller's parameterless Get action method. Viene visualizzata la risposta JSON seguente:The following JSON response is displayed:

    [
      {
        "id":"5bfd996f7b8e48dc15ff215d",
        "bookName":"Design Patterns",
        "price":54.93,
        "category":"Computers",
        "author":"Ralph Johnson"
      },
      {
        "id":"5bfd996f7b8e48dc15ff215e",
        "bookName":"Clean Code",
        "price":43.15,
        "category":"Computers",
        "author":"Robert C. Martin"
      }
    ]
    
  3. Passare a http://localhost:<port>/api/books/{id here} per testare il metodo dell'azione Get in overload del controller.Navigate to http://localhost:<port>/api/books/{id here} to test the controller's overloaded Get action method. Viene visualizzata la risposta JSON seguente:The following JSON response is displayed:

    {
      "id":"{ID}",
      "bookName":"Clean Code",
      "price":43.15,
      "category":"Computers",
      "author":"Robert C. Martin"
    }
    

Configurare le opzioni di serializzazione JSONConfigure JSON serialization options

Esistono due dettagli da modificare per le risposte JSON restituite nella sezione Testare l'API Web:There are two details to change about the JSON responses returned in the Test the web API section:

  • La notazione a cammello predefinita per i nomi di proprietà deve essere modificata in modo da adottare la convenzione Pascal dei nomi di proprietà dell'oggetto CLR.The property names' default camel casing should be changed to match the Pascal casing of the CLR object's property names.
  • La proprietà bookName deve essere restituita come Name.The bookName property should be returned as Name.

Per soddisfare i requisiti precedenti, apportare le modifiche seguenti:To satisfy the preceding requirements, make the following changes:

  1. In Startup.ConfigureServices concatenare il codice evidenziato seguente alla chiamata del metodo AddMvc:In Startup.ConfigureServices, chain the following highlighted code on to the AddMvc method call:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BookstoreDatabaseSettings>(
            Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
    
        services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
            sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
    
        services.AddSingleton<BookService>();
    
        services.AddMvc()
                .AddJsonOptions(options => options.UseMemberCasing())
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }
    

    Con la modifica precedente, i nomi delle proprietà nella risposta JSON serializzata dell'API Web corrispondono ai nomi di proprietà corrispondenti nel tipo di oggetto CLR.With the preceding change, property names in the web API's serialized JSON response match their corresponding property names in the CLR object type. Ad esempio, la proprietà Author della classe Book viene serializzata come Author.For example, the Book class's Author property serializes as Author.

  2. In models/book. csannotare la BookName proprietà con l' [JsonProperty] attributo seguente:In Models/Book.cs, annotate the BookName property with the following [JsonProperty] attribute:

    [BsonElement("Name")]
    [JsonProperty("Name")]
    public string BookName { get; set; }
    

    Il valore Name dell'attributo [JsonProperty] rappresenta il nome della proprietà nella risposta JSON serializzata dell'API Web.The [JsonProperty] attribute's value of Name represents the property name in the web API's serialized JSON response.

  3. Aggiungere il codice seguente all'inizio di Models/Book.cs per risolvere il riferimento all'attributo [JsonProperty]:Add the following code to the top of Models/Book.cs to resolve the [JsonProperty] attribute reference:

    using Newtonsoft.Json;
    
  4. Ripetere i passaggi definiti nella sezione Testare l'API Web.Repeat the steps defined in the Test the web API section. Si noti la differenza nei nomi di proprietà JSON.Notice the difference in JSON property names.

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.IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core. 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.

Passaggi successiviNext steps

Per altre informazioni sulla creazione di API Web ASP.NET Core, vedere le risorse seguenti:For more information on building ASP.NET Core web APIs, see the following resources: