Skip to content

Commit ade268a

Browse files
Adds .NET 9 sample to mongo app (#35189)
* copy-paste to 9.x * update code to .NET 9 * update references to code * update references to 8.x code * upate ms date * add missing snapshot * Update aspnetcore/tutorials/first-mongo-app.md --------- Co-authored-by: Wade Pickett <[email protected]>
1 parent 2d7329a commit ade268a

File tree

13 files changed

+326
-29
lines changed

13 files changed

+326
-29
lines changed

aspnetcore/tutorials/first-mongo-app.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ author: wadepickett
55
description: This tutorial demonstrates how to create an ASP.NET Core web API using a MongoDB NoSQL database.
66
monikerRange: '>= aspnetcore-3.1'
77
ms.author: wpickett
8-
ms.custom: mvc, engagement-fy23
9-
ms.date: 04/17/2024
8+
ms.custom: mvc
9+
ms.date: 04/09/2025
1010
uid: tutorials/first-mongo-app
1111
---
1212
# Create a web API with ASP.NET Core and MongoDB
@@ -182,7 +182,7 @@ Use the previously installed MongoDB Shell in the following steps to create a da
182182
1. Add a *Models* directory to the project root.
183183
1. Add a `Book` class to the *Models* directory with the following code:
184184

185-
:::code language="csharp" source="first-mongo-app/samples_snapshot/6.x/Book.cs":::
185+
:::code language="csharp" source="first-mongo-app/samples_snapshot/9.x/Book.cs":::
186186

187187
In the preceding class, the `Id` property is:
188188

@@ -196,48 +196,48 @@ Use the previously installed MongoDB Shell in the following steps to create a da
196196

197197
1. Add the following database configuration values to `appsettings.json`:
198198

199-
:::code language="json" source="first-mongo-app/samples/6.x/BookStoreApi/appsettings.json" highlight="2-6":::
199+
:::code language="json" source="first-mongo-app/samples/9.x/BookStoreApi/appsettings.json" highlight="2-6":::
200200

201201
1. Add a `BookStoreDatabaseSettings` class to the *Models* directory with the following code:
202202

203-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs":::
203+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs":::
204204

205205
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.
206206

207207
1. Add the following highlighted code to `Program.cs`:
208208

209-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5":::
209+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5":::
210210

211211
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`.
212212

213213
1. Add the following code to the top of `Program.cs` to resolve the `BookStoreDatabaseSettings` reference:
214214

215-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingModels":::
215+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_UsingModels":::
216216

217217
## Add a CRUD operations service
218218

219219
1. Add a *Services* directory to the project root.
220220
1. Add a `BooksService` class to the *Services* directory with the following code:
221221

222-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_File":::
222+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Services/BooksService.cs" id="snippet_File":::
223223

224224
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.
225225

226226
1. Add the following highlighted code to `Program.cs`:
227227

228-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7":::
228+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7":::
229229

230230
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.
231231

232232
1. Add the following code to the top of `Program.cs` to resolve the `BooksService` reference:
233233

234-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingServices":::
234+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_UsingServices":::
235235

236236
The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD operations against the database:
237237

238238
* [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:
239239

240-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5":::
240+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5":::
241241

242242
* [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:
243243

@@ -255,7 +255,7 @@ The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD
255255

256256
Add a `BooksController` class to the *Controllers* directory with the following code:
257257

258-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Controllers/BooksController.cs":::
258+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Controllers/BooksController.cs":::
259259

260260
The preceding web API controller:
261261

@@ -311,19 +311,19 @@ To satisfy the preceding requirements, make the following changes:
311311

312312
1. In `Program.cs`, chain the following highlighted code on to the `AddControllers` method call:
313313

314-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11":::
314+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11":::
315315

316316
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`.
317317

318318
1. In `Models/Book.cs`, annotate the `BookName` property with the [`[JsonPropertyName]`](xref:System.Text.Json.Serialization.JsonPropertyNameAttribute) attribute:
319319

320-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2":::
320+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2":::
321321

322322
The `[JsonPropertyName]` attribute's value of `Name` represents the property name in the web API's serialized JSON response.
323323

324324
1. Add the following code to the top of `Models/Book.cs` to resolve the `[JsonProperty]` attribute reference:
325325

326-
:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization":::
326+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization":::
327327

328328
1. Repeat the steps defined in the [Test the web API](#test-the-web-api) section. Notice the difference in JSON property names.
329329

@@ -333,7 +333,7 @@ To satisfy the preceding requirements, make the following changes:
333333

334334
## Additional resources
335335

336-
* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/tutorials/first-mongo-app/samples/8.x/BookStoreApi) ([how to download](xref:index#how-to-download-a-sample))
336+
* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi) ([how to download](xref:index#how-to-download-a-sample))
337337
* <xref:web-api/index>
338338
* <xref:web-api/action-return-types>
339339
* [Create a web API with ASP.NET Core](/training/modules/build-web-api-aspnet-core/)

aspnetcore/tutorials/first-mongo-app/includes/first-mongo-app8.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ Use the previously installed MongoDB Shell in the following steps to create a da
175175
1. Add a *Models* directory to the project root.
176176
1. Add a `Book` class to the *Models* directory with the following code:
177177

178-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples_snapshot/6.x/Book.cs":::
178+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples_snapshot/8.x/Book.cs":::
179179

180180
In the preceding class, the `Id` property is:
181181

@@ -189,48 +189,48 @@ Use the previously installed MongoDB Shell in the following steps to create a da
189189

190190
1. Add the following database configuration values to `appsettings.json`:
191191

192-
:::code language="json" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/appsettings.json" highlight="2-6":::
192+
:::code language="json" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/appsettings.json" highlight="2-6":::
193193

194194
1. Add a `BookStoreDatabaseSettings` class to the *Models* directory with the following code:
195195

196-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs":::
196+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs":::
197197

198198
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.
199199

200200
1. Add the following highlighted code to `Program.cs`:
201201

202-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5":::
202+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5":::
203203

204204
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`.
205205

206206
1. Add the following code to the top of `Program.cs` to resolve the `BookStoreDatabaseSettings` reference:
207207

208-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingModels":::
208+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_UsingModels":::
209209

210210
## Add a CRUD operations service
211211

212212
1. Add a *Services* directory to the project root.
213213
1. Add a `BooksService` class to the *Services* directory with the following code:
214214

215-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_File":::
215+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Services/BooksService.cs" id="snippet_File":::
216216

217217
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.
218218

219219
1. Add the following highlighted code to `Program.cs`:
220220

221-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7":::
221+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7":::
222222

223223
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.
224224

225225
1. Add the following code to the top of `Program.cs` to resolve the `BooksService` reference:
226226

227-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingServices":::
227+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_UsingServices":::
228228

229229
The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD operations against the database:
230230

231231
* [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:
232232

233-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5":::
233+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5":::
234234

235235
* [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:
236236

@@ -248,7 +248,7 @@ The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD
248248

249249
Add a `BooksController` class to the *Controllers* directory with the following code:
250250

251-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Controllers/BooksController.cs":::
251+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Controllers/BooksController.cs":::
252252

253253
The preceding web API controller:
254254

@@ -304,19 +304,19 @@ To satisfy the preceding requirements, make the following changes:
304304

305305
1. In `Program.cs`, chain the following highlighted code on to the `AddControllers` method call:
306306

307-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11":::
307+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11":::
308308

309309
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`.
310310

311311
1. In `Models/Book.cs`, annotate the `BookName` property with the [`[JsonPropertyName]`](xref:System.Text.Json.Serialization.JsonPropertyNameAttribute) attribute:
312312

313-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2":::
313+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2":::
314314

315315
The `[JsonPropertyName]` attribute's value of `Name` represents the property name in the web API's serialized JSON response.
316316

317317
1. Add the following code to the top of `Models/Book.cs` to resolve the `[JsonProperty]` attribute reference:
318318

319-
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization":::
319+
:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization":::
320320

321321
1. Repeat the steps defined in the [Test the web API](#test-the-web-api) section. Notice the difference in JSON property names.
322322

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4" />
11+
<PackageReference Include="MongoDB.Driver" Version="3.3.0" />
12+
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.0" />
13+
</ItemGroup>
14+
15+
</Project>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using BookStoreApi.Models;
2+
using BookStoreApi.Services;
3+
using Microsoft.AspNetCore.Mvc;
4+
5+
namespace BookStoreApi.Controllers;
6+
7+
[ApiController]
8+
[Route("api/[controller]")]
9+
public class BooksController : ControllerBase
10+
{
11+
private readonly BooksService _booksService;
12+
13+
public BooksController(BooksService booksService) =>
14+
_booksService = booksService;
15+
16+
[HttpGet]
17+
public async Task<List<Book>> Get() =>
18+
await _booksService.GetAsync();
19+
20+
[HttpGet("{id:length(24)}")]
21+
public async Task<ActionResult<Book>> Get(string id)
22+
{
23+
var book = await _booksService.GetAsync(id);
24+
25+
if (book is null)
26+
{
27+
return NotFound();
28+
}
29+
30+
return book;
31+
}
32+
33+
[HttpPost]
34+
public async Task<IActionResult> Post(Book newBook)
35+
{
36+
await _booksService.CreateAsync(newBook);
37+
38+
return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook);
39+
}
40+
41+
[HttpPut("{id:length(24)}")]
42+
public async Task<IActionResult> Update(string id, Book updatedBook)
43+
{
44+
var book = await _booksService.GetAsync(id);
45+
46+
if (book is null)
47+
{
48+
return NotFound();
49+
}
50+
51+
updatedBook.Id = book.Id;
52+
53+
await _booksService.UpdateAsync(id, updatedBook);
54+
55+
return NoContent();
56+
}
57+
58+
[HttpDelete("{id:length(24)}")]
59+
public async Task<IActionResult> Delete(string id)
60+
{
61+
var book = await _booksService.GetAsync(id);
62+
63+
if (book is null)
64+
{
65+
return NotFound();
66+
}
67+
68+
await _booksService.RemoveAsync(id);
69+
70+
return NoContent();
71+
}
72+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
3+
namespace BookStoreApi.Controllers;
4+
5+
[ApiController]
6+
[Route("[controller]")]
7+
public class WeatherForecastController : ControllerBase
8+
{
9+
private static readonly string[] Summaries = new[]
10+
{
11+
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
12+
};
13+
14+
private readonly ILogger<WeatherForecastController> _logger;
15+
16+
public WeatherForecastController(ILogger<WeatherForecastController> logger)
17+
{
18+
_logger = logger;
19+
}
20+
21+
[HttpGet(Name = "GetWeatherForecast")]
22+
public IEnumerable<WeatherForecast> Get()
23+
{
24+
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
25+
{
26+
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
27+
TemperatureC = Random.Shared.Next(-20, 55),
28+
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
29+
})
30+
.ToArray();
31+
}
32+
}

0 commit comments

Comments
 (0)