Skip to content

Commit 77af002

Browse files
committed
copy current document to v8 page
1 parent e84d36f commit 77af002

File tree

2 files changed

+339
-1
lines changed

2 files changed

+339
-1
lines changed

aspnetcore/tutorials/first-mongo-app.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ uid: tutorials/first-mongo-app
1515

1616
By [Pratik Khandelwal](https://twitter.com/K2Prk) and [Scott Addie](https://twitter.com/Scott_Addie)
1717

18-
:::moniker range=">= aspnetcore-8.0"
18+
:::moniker range=">= aspnetcore-9.0"
1919

2020
This tutorial creates a web API that runs Create, Read, Update, and Delete (CRUD) operations on a [MongoDB](https://www.mongodb.com/what-is-mongodb) NoSQL database.
2121

@@ -352,6 +352,8 @@ To satisfy the preceding requirements, make the following changes:
352352

353353
:::moniker-end
354354

355+
[!INCLUDE[](~/tutorials/first-mongo-app/includes/first-mongo-app8.md)]
356+
355357
[!INCLUDE[](~/tutorials/first-mongo-app/includes/first-mongo-app7.md)]
356358

357359
[!INCLUDE[](~/tutorials/first-mongo-app/includes/first-mongo-app6.md)]
Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
:::moniker range="= aspnetcore-8.0"
2+
3+
This tutorial creates a web API that runs Create, Read, Update, and Delete (CRUD) operations on a [MongoDB](https://www.mongodb.com/what-is-mongodb) NoSQL database.
4+
5+
In this tutorial, you learn how to:
6+
7+
> [!div class="checklist"]
8+
> * Configure MongoDB
9+
> * Create a MongoDB database
10+
> * Define a MongoDB collection and schema
11+
> * Perform MongoDB CRUD operations from a web API
12+
> * Customize JSON serialization
13+
14+
## Prerequisites
15+
16+
* [MongoDB 6.0.5 or later](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/)
17+
* [MongoDB Shell](https://www.mongodb.com/docs/mongodb-shell/install/)
18+
19+
# [Visual Studio](#tab/visual-studio)
20+
21+
[!INCLUDE[](~/includes/net-prereqs-vs-8.0.md)]
22+
23+
# [Visual Studio Code](#tab/visual-studio-code)
24+
25+
[!INCLUDE[](~/includes/net-prereqs-vsc-8.0.md)]
26+
27+
# [Visual Studio for Mac](#tab/visual-studio-mac)
28+
29+
[!INCLUDE[](~/includes/net-prereqs-mac-8.0.md)]
30+
31+
---
32+
33+
## Configure MongoDB
34+
35+
36+
Enable MongoDB and MongoDB Shell access from anywhere on the development machine (Windows/Linux/macOS):
37+
38+
1. Download and Install MongoDB Shell:
39+
* macOS/Linux: Choose a directory to extract the MongoDB Shell to. Add the resulting path for `mongosh` to the `PATH` environment variable.
40+
* Windows: MongoDB Shell (mongosh.exe) is installed at *C:\Users\<user>\AppData\Local\Programs\mongosh*. Add the resulting path for `mongosh.exe` to the `PATH` environment variable.
41+
1. Download and Install MongoDB:
42+
* macOS/Linux: Verify the directory that MongoDB was installed at, usually in */usr/local/mongodb*. Add the resulting path for `mongodb` to the `PATH` environment variable.
43+
* Windows: MongoDB is installed at *C:\\Program Files\MongoDB* by default. Add *C:\\Program Files\\MongoDB\\Server\\\<version_number>\\bin* to the `PATH` environment variable.
44+
1. Choose a Data Storage Directory: Select a directory on your development machine for storing data. Create the directory if it doesn't exist. The MongoDB Shell doesn't create new directories:
45+
* macOS/Linux: For example, `/usr/local/var/mongodb`.
46+
* Windows: For example, `C:\\BooksData`.
47+
1. In the OS command shell (not the MongoDB Shell), use the following command to connect to MongoDB on default port 27017. Replace `<data_directory_path>` with the directory chosen in the previous step.
48+
49+
```console
50+
mongod --dbpath <data_directory_path>
51+
```
52+
53+
Use the previously installed MongoDB Shell in the following steps to create a database, make collections, and store documents. For more information on MongoDB Shell commands, see [`mongosh`](https://docs.mongodb.com/mongodb-shell/run-commands/).
54+
55+
1. Open a MongoDB command shell instance by launching `mongosh.exe`.
56+
1. In the command shell, connect to the default test database by running the following command:
57+
58+
```console
59+
mongosh
60+
```
61+
62+
1. Run the following command in the command shell:
63+
64+
```console
65+
use BookStore
66+
```
67+
68+
A database named *BookStore* is created if it doesn't already exist. If the database does exist, its connection is opened for transactions.
69+
70+
1. Create a `Books` collection using following command:
71+
72+
```console
73+
db.createCollection('Books')
74+
```
75+
76+
The following result is displayed:
77+
78+
```console
79+
{ "ok" : 1 }
80+
```
81+
82+
1. Define a schema for the `Books` collection and insert two documents using the following command:
83+
84+
```console
85+
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" }])
86+
```
87+
88+
A result similar to the following is displayed:
89+
90+
```console
91+
{
92+
"acknowledged" : true,
93+
"insertedIds" : [
94+
ObjectId("61a6058e6c43f32854e51f51"),
95+
ObjectId("61a6058e6c43f32854e51f52")
96+
]
97+
}
98+
```
99+
100+
> [!NOTE]
101+
> The `ObjectId`s shown in the preceding result won't match those shown in the command shell.
102+
103+
1. View the documents in the database using the following command:
104+
105+
```console
106+
db.Books.find().pretty()
107+
```
108+
109+
A result similar to the following is displayed:
110+
111+
```console
112+
{
113+
"_id" : ObjectId("61a6058e6c43f32854e51f51"),
114+
"Name" : "Design Patterns",
115+
"Price" : 54.93,
116+
"Category" : "Computers",
117+
"Author" : "Ralph Johnson"
118+
}
119+
{
120+
"_id" : ObjectId("61a6058e6c43f32854e51f52"),
121+
"Name" : "Clean Code",
122+
"Price" : 43.15,
123+
"Category" : "Computers",
124+
"Author" : "Robert C. Martin"
125+
}
126+
```
127+
128+
The schema adds an autogenerated `_id` property of type `ObjectId` for each document.
129+
130+
## Create the ASP.NET Core web API project
131+
132+
# [Visual Studio](#tab/visual-studio)
133+
134+
1. Go to **File** > **New** > **Project**.
135+
1. Select the **ASP.NET Core Web API** project type, and select **Next**.
136+
1. Name the project *BookStoreApi*, and select **Next**.
137+
1. Select the **.NET 8.0 (Long Term support)** framework and select **Create**.
138+
1. In the **Package Manager Console** window, navigate to the project root. Run the following command to install the .NET driver for MongoDB:
139+
140+
```powershell
141+
Install-Package MongoDB.Driver
142+
```
143+
144+
# [Visual Studio Code](#tab/visual-studio-code)
145+
146+
1. Run the following commands in a command shell:
147+
148+
```dotnetcli
149+
dotnet new webapi -o BookStoreApi
150+
code BookStoreApi
151+
```
152+
153+
The preceding commands generate a new ASP.NET Core web API project and then open the project in Visual Studio Code.
154+
155+
1. Once the OmniSharp server starts up, a dialog asks **Required assets to build and debug are missing from 'BookStoreApi'. Add them?**. Select **Yes**.
156+
1. Open the **Integrated Terminal** and run the following command to install the .NET driver for MongoDB:
157+
158+
```dotnetcli
159+
dotnet add package MongoDB.Driver
160+
```
161+
162+
# [Visual Studio for Mac](#tab/visual-studio-mac)
163+
164+
1. Select **File** > **New Project...**.
165+
1. Select **Web and Console** > **App** from the sidebar.
166+
1. Select the **ASP.NET Core** > **API** C# project template, and select **Next**.
167+
1. Select **.NET 8.0** from the **Target Framework** drop-down list, and select **Next**.
168+
1. Enter *BookStoreApi* for the **Project Name**, and select **Create**.
169+
1. In the **Solution** pad, right-click the project's **Dependencies** node and select **Manage NuGet Packages**.
170+
1. Enter *MongoDB.Driver* in the search box, select the *MongoDB.Driver* package, and select **Add Package**.
171+
1. Select the **Accept** button in the **License Acceptance** dialog.
172+
173+
---
174+
175+
## Add an entity model
176+
177+
1. Add a *Models* directory to the project root.
178+
1. Add a `Book` class to the *Models* directory with the following code:
179+
180+
:::code language="csharp" source="first-mongo-app/samples_snapshot/6.x/Book.cs":::
181+
182+
In the preceding class, the `Id` property is:
183+
184+
* Required for mapping the Common Language Runtime (CLR) object to the MongoDB collection.
185+
* Annotated with [`[BsonId]`](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/T_MongoDB_Bson_Serialization_Attributes_BsonIdAttribute.htm) to make this property the document's primary key.
186+
* Annotated with [`[BsonRepresentation(BsonType.ObjectId)]`](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/T_MongoDB_Bson_Serialization_Attributes_BsonRepresentationAttribute.htm) to allow passing the parameter as type `string` instead of an [ObjectId](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/T_MongoDB_Bson_ObjectId.htm) structure. Mongo handles the conversion from `string` to `ObjectId`.
187+
188+
The `BookName` property is annotated with the [`[BsonElement]`](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/T_MongoDB_Bson_Serialization_Attributes_BsonElementAttribute.htm) attribute. The attribute's value of `Name` represents the property name in the MongoDB collection.
189+
190+
## Add a configuration model
191+
192+
1. Add the following database configuration values to `appsettings.json`:
193+
194+
:::code language="json" source="first-mongo-app/samples/6.x/BookStoreApi/appsettings.json" highlight="2-6":::
195+
196+
1. Add a `BookStoreDatabaseSettings` class to the *Models* directory with the following code:
197+
198+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs":::
199+
200+
The preceding `BookStoreDatabaseSettings` class is used to store the `appsettings.json` file's `BookStoreDatabase` property values. The JSON and C# property names are named identically to ease the mapping process.
201+
202+
1. Add the following highlighted code to `Program.cs`:
203+
204+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5":::
205+
206+
In the preceding code, the configuration instance to which the `appsettings.json` file's `BookStoreDatabase` section binds is registered in the Dependency Injection (DI) container. For example, the `BookStoreDatabaseSettings` object's `ConnectionString` property is populated with the `BookStoreDatabase:ConnectionString` property in `appsettings.json`.
207+
208+
1. Add the following code to the top of `Program.cs` to resolve the `BookStoreDatabaseSettings` reference:
209+
210+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingModels":::
211+
212+
## Add a CRUD operations service
213+
214+
1. Add a *Services* directory to the project root.
215+
1. Add a `BooksService` class to the *Services* directory with the following code:
216+
217+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_File":::
218+
219+
In the preceding code, a `BookStoreDatabaseSettings` instance is retrieved from DI via constructor injection. This technique provides access to the `appsettings.json` configuration values that were added in the [Add a configuration model](#add-a-configuration-model) section.
220+
221+
1. Add the following highlighted code to `Program.cs`:
222+
223+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7":::
224+
225+
In the preceding code, the `BooksService` class is registered with DI to support constructor injection in consuming classes. The singleton service lifetime is most appropriate because `BooksService` takes a direct dependency on `MongoClient`. Per the official [Mongo Client reuse guidelines](https://mongodb.github.io/mongo-csharp-driver/2.14/reference/driver/connecting/#re-use), `MongoClient` should be registered in DI with a singleton service lifetime.
226+
227+
1. Add the following code to the top of `Program.cs` to resolve the `BooksService` reference:
228+
229+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingServices":::
230+
231+
The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD operations against the database:
232+
233+
* [MongoClient](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/T_MongoDB_Driver_MongoClient.htm): Reads the server instance for running database operations. The constructor of this class is provided in the MongoDB connection string:
234+
235+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5":::
236+
237+
* [IMongoDatabase](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/T_MongoDB_Driver_IMongoDatabase.htm): Represents the Mongo database for running operations. This tutorial uses the generic [GetCollection\<TDocument>(collection)](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/M_MongoDB_Driver_IMongoDatabase_GetCollection__1.htm) method on the interface to gain access to data in a specific collection. Run CRUD operations against the collection after this method is called. In the `GetCollection<TDocument>(collection)` method call:
238+
239+
* `collection` represents the collection name.
240+
* `TDocument` represents the CLR object type stored in the collection.
241+
242+
`GetCollection<TDocument>(collection)` returns a [MongoCollection](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/T_MongoDB_Driver_MongoCollection.htm) object representing the collection. In this tutorial, the following methods are invoked on the collection:
243+
244+
* [DeleteOneAsync](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/M_MongoDB_Driver_IMongoCollection_1_DeleteOneAsync_1.htm): Deletes a single document matching the provided search criteria.
245+
* [Find\<TDocument>](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/M_MongoDB_Driver_IMongoCollectionExtensions_Find__1.htm): Returns all documents in the collection matching the provided search criteria.
246+
* [InsertOneAsync](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/M_MongoDB_Driver_IMongoCollection_1_InsertOneAsync_1.htm): Inserts the provided object as a new document in the collection.
247+
* [ReplaceOneAsync](https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/M_MongoDB_Driver_IMongoCollection_1_ReplaceOneAsync.htm): Replaces the single document matching the provided search criteria with the provided object.
248+
249+
## Add a controller
250+
251+
Add a `BooksController` class to the *Controllers* directory with the following code:
252+
253+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Controllers/BooksController.cs":::
254+
255+
The preceding web API controller:
256+
257+
* Uses the `BooksService` class to run CRUD operations.
258+
* Contains action methods to support GET, POST, PUT, and DELETE HTTP requests.
259+
* Calls <xref:Microsoft.AspNetCore.Mvc.ControllerBase.CreatedAtAction%2A> in the `Create` action method to return an [HTTP 201](https://www.rfc-editor.org/rfc/rfc9110#status.201) response. Status code 201 is the standard response for an HTTP POST method that creates a new resource on the server. `CreatedAtAction` also adds a `Location` header to the response. The `Location` header specifies the URI of the newly created book.
260+
261+
## Test the web API
262+
263+
1. Build and run the app.
264+
265+
1. Navigate to `https://localhost:<port>/api/books`, where `<port>` is the automatically assigned port number for the app, to test the controller's parameterless `Get` action method, select **Try it out** > **Execute**. A JSON response similar to the following is displayed:
266+
267+
```json
268+
[
269+
{
270+
"id": "61a6058e6c43f32854e51f51",
271+
"bookName": "Design Patterns",
272+
"price": 54.93,
273+
"category": "Computers",
274+
"author": "Ralph Johnson"
275+
},
276+
{
277+
"id": "61a6058e6c43f32854e51f52",
278+
"bookName": "Clean Code",
279+
"price": 43.15,
280+
"category": "Computers",
281+
"author": "Robert C. Martin"
282+
}
283+
]
284+
```
285+
286+
1. Navigate to `https://localhost:<port>/api/books/{id here}` to test the controller's overloaded `Get` action method. A JSON response similar to the following is displayed:
287+
288+
```json
289+
{
290+
"id": "61a6058e6c43f32854e51f52",
291+
"bookName": "Clean Code",
292+
"price": 43.15,
293+
"category": "Computers",
294+
"author": "Robert C. Martin"
295+
}
296+
```
297+
298+
## Configure JSON serialization options
299+
300+
There are two details to change about the JSON responses returned in the [Test the web API](#test-the-web-api) section:
301+
302+
* The property names' default camel casing should be changed to match the Pascal casing of the CLR object's property names.
303+
* The `bookName` property should be returned as `Name`.
304+
305+
To satisfy the preceding requirements, make the following changes:
306+
307+
1. In `Program.cs`, chain the following highlighted code on to the `AddControllers` method call:
308+
309+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11":::
310+
311+
With the preceding change, property names in the web API's serialized JSON response match their corresponding property names in the CLR object type. For example, the `Book` class's `Author` property serializes as `Author` instead of `author`.
312+
313+
1. In `Models/Book.cs`, annotate the `BookName` property with the [`[JsonPropertyName]`](xref:System.Text.Json.Serialization.JsonPropertyNameAttribute) attribute:
314+
315+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2":::
316+
317+
The `[JsonPropertyName]` attribute's value of `Name` represents the property name in the web API's serialized JSON response.
318+
319+
1. Add the following code to the top of `Models/Book.cs` to resolve the `[JsonProperty]` attribute reference:
320+
321+
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization":::
322+
323+
1. Repeat the steps defined in the [Test the web API](#test-the-web-api) section. Notice the difference in JSON property names.
324+
325+
## Add authentication support to a web API
326+
327+
[!INCLUDE[](~/includes/DuendeIdentityServer.md)]
328+
329+
## Additional resources
330+
331+
* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/tutorials/first-mongo-app/samples) ([how to download](xref:index#how-to-download-a-sample))
332+
* <xref:web-api/index>
333+
* <xref:web-api/action-return-types>
334+
* [Create a web API with ASP.NET Core](/training/modules/build-web-api-aspnet-core/)
335+
336+
:::moniker-end

0 commit comments

Comments
 (0)