From b540a688d74ec5b3a2006dee2c69473b536115d6 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Wed, 9 Apr 2025 18:36:17 +0200 Subject: [PATCH 1/7] copy-paste to 9.x --- .../9.x/BookStoreApi/BookStoreApi.csproj | 15 ++++ .../Controllers/BooksController.cs | 72 +++++++++++++++++++ .../Controllers/WeatherForecastController.cs | 33 +++++++++ .../samples/9.x/BookStoreApi/Models/Book.cs | 26 +++++++ .../Models/BookStoreDatabaseSettings.cs | 10 +++ .../samples/9.x/BookStoreApi/Program.cs | 44 ++++++++++++ .../9.x/BookStoreApi/Services/BooksService.cs | 42 +++++++++++ .../9.x/BookStoreApi/WeatherForecast.cs | 13 ++++ .../BookStoreApi/appsettings.Development.json | 8 +++ .../samples/9.x/BookStoreApi/appsettings.json | 14 ++++ 10 files changed, 277 insertions(+) create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/BooksController.cs create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Models/Book.cs create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Services/BooksService.cs create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/appsettings.Development.json create mode 100644 aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/appsettings.json diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj new file mode 100644 index 000000000000..d2b95707f5f3 --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + + + + + + + + + diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/BooksController.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/BooksController.cs new file mode 100644 index 000000000000..a163070b293f --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/BooksController.cs @@ -0,0 +1,72 @@ +using BookStoreApi.Models; +using BookStoreApi.Services; +using Microsoft.AspNetCore.Mvc; + +namespace BookStoreApi.Controllers; + +[ApiController] +[Route("api/[controller]")] +public class BooksController : ControllerBase +{ + private readonly BooksService _booksService; + + public BooksController(BooksService booksService) => + _booksService = booksService; + + [HttpGet] + public async Task> Get() => + await _booksService.GetAsync(); + + [HttpGet("{id:length(24)}")] + public async Task> Get(string id) + { + var book = await _booksService.GetAsync(id); + + if (book is null) + { + return NotFound(); + } + + return book; + } + + [HttpPost] + public async Task Post(Book newBook) + { + await _booksService.CreateAsync(newBook); + + return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook); + } + + [HttpPut("{id:length(24)}")] + public async Task Update(string id, Book updatedBook) + { + var book = await _booksService.GetAsync(id); + + if (book is null) + { + return NotFound(); + } + + updatedBook.Id = book.Id; + + await _booksService.UpdateAsync(id, updatedBook); + + return NoContent(); + } + + [HttpDelete("{id:length(24)}")] + public async Task Delete(string id) + { + var book = await _booksService.GetAsync(id); + + if (book is null) + { + return NotFound(); + } + + await _booksService.RemoveAsync(id); + + return NoContent(); + } +} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs new file mode 100644 index 000000000000..4135e8363f38 --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace BookStoreApi.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Models/Book.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Models/Book.cs new file mode 100644 index 000000000000..93f1a7ab4d3a --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Models/Book.cs @@ -0,0 +1,26 @@ +// +using System.Text.Json.Serialization; +// +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace BookStoreApi.Models; + +public class Book +{ + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string? Id { get; set; } + + // + [BsonElement("Name")] + [JsonPropertyName("Name")] + public string BookName { get; set; } = null!; + // + + public decimal Price { get; set; } + + public string Category { get; set; } = null!; + + public string Author { get; set; } = null!; +} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs new file mode 100644 index 000000000000..edfe7ebb6054 --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs @@ -0,0 +1,10 @@ +namespace BookStoreApi.Models; + +public class BookStoreDatabaseSettings +{ + public string ConnectionString { get; set; } = null!; + + public string DatabaseName { get; set; } = null!; + + public string BooksCollectionName { get; set; } = null!; +} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs new file mode 100644 index 000000000000..68c00d3561f8 --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs @@ -0,0 +1,44 @@ +// +using BookStoreApi.Models; +// +// +using BookStoreApi.Services; +// + +// +// +// +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.Configure( + builder.Configuration.GetSection("BookStoreDatabase")); +// + +builder.Services.AddSingleton(); +// + +builder.Services.AddControllers() + .AddJsonOptions( + options => options.JsonSerializerOptions.PropertyNamingPolicy = null); +// + +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Services/BooksService.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Services/BooksService.cs new file mode 100644 index 000000000000..3565c8b43606 --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Services/BooksService.cs @@ -0,0 +1,42 @@ +// +using BookStoreApi.Models; +using Microsoft.Extensions.Options; +using MongoDB.Driver; + +namespace BookStoreApi.Services; + +public class BooksService +{ + private readonly IMongoCollection _booksCollection; + + // + public BooksService( + IOptions bookStoreDatabaseSettings) + { + var mongoClient = new MongoClient( + bookStoreDatabaseSettings.Value.ConnectionString); + + var mongoDatabase = mongoClient.GetDatabase( + bookStoreDatabaseSettings.Value.DatabaseName); + + _booksCollection = mongoDatabase.GetCollection( + bookStoreDatabaseSettings.Value.BooksCollectionName); + } + // + + public async Task> GetAsync() => + await _booksCollection.Find(_ => true).ToListAsync(); + + public async Task GetAsync(string id) => + await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync(); + + public async Task CreateAsync(Book newBook) => + await _booksCollection.InsertOneAsync(newBook); + + public async Task UpdateAsync(string id, Book updatedBook) => + await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook); + + public async Task RemoveAsync(string id) => + await _booksCollection.DeleteOneAsync(x => x.Id == id); +} +// diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs new file mode 100644 index 000000000000..70fc455bb7ec --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace BookStoreApi +{ + public class WeatherForecast + { + public DateOnly Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } + } +} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/appsettings.Development.json b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/appsettings.Development.json new file mode 100644 index 000000000000..0c208ae9181e --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/appsettings.json b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/appsettings.json new file mode 100644 index 000000000000..db0fa877639d --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/appsettings.json @@ -0,0 +1,14 @@ +{ + "BookStoreDatabase": { + "ConnectionString": "mongodb://localhost:27017", + "DatabaseName": "BookStore", + "BooksCollectionName": "Books" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} From f3c326599574fe132aff1279296b2e1abe8f98a7 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Wed, 9 Apr 2025 19:09:05 +0200 Subject: [PATCH 2/7] update code to .NET 9 --- .../9.x/BookStoreApi/BookStoreApi.csproj | 8 ++-- .../Controllers/WeatherForecastController.cs | 41 +++++++++---------- .../samples/9.x/BookStoreApi/Program.cs | 10 +++-- .../9.x/BookStoreApi/WeatherForecast.cs | 17 ++++---- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj index d2b95707f5f3..2e03412c3803 100644 --- a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj @@ -1,15 +1,15 @@ - net8.0 + net9.0 enable enable - - - + + + diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs index 4135e8363f38..c06604cb988a 100644 --- a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs @@ -1,33 +1,32 @@ using Microsoft.AspNetCore.Mvc; -namespace BookStoreApi.Controllers +namespace BookStoreApi.Controllers; + +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase { - [ApiController] - [Route("[controller]")] - public class WeatherForecastController : ControllerBase + private static readonly string[] Summaries = new[] { - private static readonly string[] Summaries = new[] - { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; - private readonly ILogger _logger; + private readonly ILogger _logger; - public WeatherForecastController(ILogger logger) - { - _logger = logger; - } + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } - [HttpGet(Name = "GetWeatherForecast")] - public IEnumerable Get() + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast { - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = Summaries[Random.Shared.Next(Summaries.Length)] - }) - .ToArray(); - } + Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); } } \ No newline at end of file diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs index 68c00d3561f8..75fb976c8077 100644 --- a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs @@ -23,16 +23,18 @@ options => options.JsonSerializerOptions.PropertyNamingPolicy = null); // -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); +builder.Services.AddOpenApi(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { - app.UseSwagger(); - app.UseSwaggerUI(); + app.MapOpenApi(); + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/openapi/v1.json", "v1"); + }); } app.UseHttpsRedirection(); diff --git a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs index 70fc455bb7ec..840bfce93bf5 100644 --- a/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs +++ b/aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs @@ -1,13 +1,12 @@ -namespace BookStoreApi +namespace BookStoreApi; + +public class WeatherForecast { - public class WeatherForecast - { - public DateOnly Date { get; set; } + public DateOnly Date { get; set; } - public int TemperatureC { get; set; } + public int TemperatureC { get; set; } - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - public string? Summary { get; set; } - } -} \ No newline at end of file + public string? Summary { get; set; } +} From 031e2f0b2f7798adcd3e5f23ae98b34e33e5e692 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Wed, 9 Apr 2025 19:09:13 +0200 Subject: [PATCH 3/7] update references to code --- aspnetcore/tutorials/first-mongo-app.md | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/aspnetcore/tutorials/first-mongo-app.md b/aspnetcore/tutorials/first-mongo-app.md index f8111ffba171..ebd25463d10e 100644 --- a/aspnetcore/tutorials/first-mongo-app.md +++ b/aspnetcore/tutorials/first-mongo-app.md @@ -182,7 +182,7 @@ Use the previously installed MongoDB Shell in the following steps to create a da 1. Add a *Models* directory to the project root. 1. Add a `Book` class to the *Models* directory with the following code: - :::code language="csharp" source="first-mongo-app/samples_snapshot/6.x/Book.cs"::: + :::code language="csharp" source="first-mongo-app/samples_snapshot/9.x/Book.cs"::: In the preceding class, the `Id` property is: @@ -196,48 +196,48 @@ Use the previously installed MongoDB Shell in the following steps to create a da 1. Add the following database configuration values to `appsettings.json`: - :::code language="json" source="first-mongo-app/samples/6.x/BookStoreApi/appsettings.json" highlight="2-6"::: + :::code language="json" source="first-mongo-app/samples/9.x/BookStoreApi/appsettings.json" highlight="2-6"::: 1. Add a `BookStoreDatabaseSettings` class to the *Models* directory with the following code: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs"::: 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. 1. Add the following highlighted code to `Program.cs`: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5"::: 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`. 1. Add the following code to the top of `Program.cs` to resolve the `BookStoreDatabaseSettings` reference: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingModels"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_UsingModels"::: ## Add a CRUD operations service 1. Add a *Services* directory to the project root. 1. Add a `BooksService` class to the *Services* directory with the following code: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_File"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Services/BooksService.cs" id="snippet_File"::: 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. 1. Add the following highlighted code to `Program.cs`: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7"::: 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. 1. Add the following code to the top of `Program.cs` to resolve the `BooksService` reference: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingServices"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_UsingServices"::: The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD operations against the database: * [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: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5"::: * [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\(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(collection)` method call: @@ -255,7 +255,7 @@ The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD Add a `BooksController` class to the *Controllers* directory with the following code: -:::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Controllers/BooksController.cs"::: +:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Controllers/BooksController.cs"::: The preceding web API controller: @@ -311,19 +311,19 @@ To satisfy the preceding requirements, make the following changes: 1. In `Program.cs`, chain the following highlighted code on to the `AddControllers` method call: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11"::: 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`. 1. In `Models/Book.cs`, annotate the `BookName` property with the [`[JsonPropertyName]`](xref:System.Text.Json.Serialization.JsonPropertyNameAttribute) attribute: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2"::: The `[JsonPropertyName]` attribute's value of `Name` represents the property name in the web API's serialized JSON response. 1. Add the following code to the top of `Models/Book.cs` to resolve the `[JsonProperty]` attribute reference: - :::code language="csharp" source="first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization"::: + :::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization"::: 1. Repeat the steps defined in the [Test the web API](#test-the-web-api) section. Notice the difference in JSON property names. @@ -333,7 +333,7 @@ To satisfy the preceding requirements, make the following changes: ## Additional resources -* [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)) +* [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)) * * * [Create a web API with ASP.NET Core](/training/modules/build-web-api-aspnet-core/) From a3139f14a3786188957a3d37b00dcf95ebe0e903 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Wed, 9 Apr 2025 19:09:36 +0200 Subject: [PATCH 4/7] update references to 8.x code --- .../includes/first-mongo-app8.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/aspnetcore/tutorials/first-mongo-app/includes/first-mongo-app8.md b/aspnetcore/tutorials/first-mongo-app/includes/first-mongo-app8.md index 6af18426df2b..b68145e8734b 100644 --- a/aspnetcore/tutorials/first-mongo-app/includes/first-mongo-app8.md +++ b/aspnetcore/tutorials/first-mongo-app/includes/first-mongo-app8.md @@ -175,7 +175,7 @@ Use the previously installed MongoDB Shell in the following steps to create a da 1. Add a *Models* directory to the project root. 1. Add a `Book` class to the *Models* directory with the following code: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples_snapshot/6.x/Book.cs"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples_snapshot/8.x/Book.cs"::: In the preceding class, the `Id` property is: @@ -189,48 +189,48 @@ Use the previously installed MongoDB Shell in the following steps to create a da 1. Add the following database configuration values to `appsettings.json`: - :::code language="json" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/appsettings.json" highlight="2-6"::: + :::code language="json" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/appsettings.json" highlight="2-6"::: 1. Add a `BookStoreDatabaseSettings` class to the *Models* directory with the following code: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Models/BookStoreDatabaseSettings.cs"::: 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. 1. Add the following highlighted code to `Program.cs`: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_BookStoreDatabaseSettings" highlight="4-5"::: 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`. 1. Add the following code to the top of `Program.cs` to resolve the `BookStoreDatabaseSettings` reference: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingModels"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_UsingModels"::: ## Add a CRUD operations service 1. Add a *Services* directory to the project root. 1. Add a `BooksService` class to the *Services* directory with the following code: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_File"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Services/BooksService.cs" id="snippet_File"::: 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. 1. Add the following highlighted code to `Program.cs`: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_BooksService" highlight="7"::: 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. 1. Add the following code to the top of `Program.cs` to resolve the `BooksService` reference: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_UsingServices"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_UsingServices"::: The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD operations against the database: * [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: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Services/BooksService.cs" id="snippet_ctor" highlight="4-5"::: * [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\(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(collection)` method call: @@ -248,7 +248,7 @@ The `BooksService` class uses the following `MongoDB.Driver` members to run CRUD Add a `BooksController` class to the *Controllers* directory with the following code: -:::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Controllers/BooksController.cs"::: +:::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Controllers/BooksController.cs"::: The preceding web API controller: @@ -304,19 +304,19 @@ To satisfy the preceding requirements, make the following changes: 1. In `Program.cs`, chain the following highlighted code on to the `AddControllers` method call: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Program.cs" id="snippet_AddControllers" highlight="10-11"::: 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`. 1. In `Models/Book.cs`, annotate the `BookName` property with the [`[JsonPropertyName]`](xref:System.Text.Json.Serialization.JsonPropertyNameAttribute) attribute: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Models/Book.cs" id="snippet_BookName" highlight="2"::: The `[JsonPropertyName]` attribute's value of `Name` represents the property name in the web API's serialized JSON response. 1. Add the following code to the top of `Models/Book.cs` to resolve the `[JsonProperty]` attribute reference: - :::code language="csharp" source="~/tutorials/first-mongo-app/samples/6.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization"::: + :::code language="csharp" source="~/tutorials/first-mongo-app/samples/8.x/BookStoreApi/Models/Book.cs" id="snippet_UsingSystemTextJsonSerialization"::: 1. Repeat the steps defined in the [Test the web API](#test-the-web-api) section. Notice the difference in JSON property names. From d321b62e77bf39d18c7c2ffc8a823b00e4a43d2e Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Wed, 9 Apr 2025 19:56:01 +0200 Subject: [PATCH 5/7] upate ms date --- aspnetcore/tutorials/first-mongo-app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/tutorials/first-mongo-app.md b/aspnetcore/tutorials/first-mongo-app.md index ebd25463d10e..b678367382d4 100644 --- a/aspnetcore/tutorials/first-mongo-app.md +++ b/aspnetcore/tutorials/first-mongo-app.md @@ -6,7 +6,7 @@ description: This tutorial demonstrates how to create an ASP.NET Core web API us monikerRange: '>= aspnetcore-3.1' ms.author: wpickett ms.custom: mvc, engagement-fy23 -ms.date: 04/17/2024 +ms.date: 04/09/2025 uid: tutorials/first-mongo-app --- # Create a web API with ASP.NET Core and MongoDB From 1c1eceb3efc8388a2262b1bf926bfd5fd6fc1319 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Wed, 9 Apr 2025 20:05:32 +0200 Subject: [PATCH 6/7] add missing snapshot --- .../samples_snapshot/9.x/Book.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 aspnetcore/tutorials/first-mongo-app/samples_snapshot/9.x/Book.cs diff --git a/aspnetcore/tutorials/first-mongo-app/samples_snapshot/9.x/Book.cs b/aspnetcore/tutorials/first-mongo-app/samples_snapshot/9.x/Book.cs new file mode 100644 index 000000000000..97756d7d5d5a --- /dev/null +++ b/aspnetcore/tutorials/first-mongo-app/samples_snapshot/9.x/Book.cs @@ -0,0 +1,20 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace BookStoreApi.Models; + +public class Book +{ + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string? Id { get; set; } + + [BsonElement("Name")] + public string BookName { get; set; } = null!; + + public decimal Price { get; set; } + + public string Category { get; set; } = null!; + + public string Author { get; set; } = null!; +} From b282bb896a96d2cfa7d9a09a227785af4cfa36dc Mon Sep 17 00:00:00 2001 From: Wade Pickett Date: Wed, 9 Apr 2025 15:08:08 -0700 Subject: [PATCH 7/7] Update aspnetcore/tutorials/first-mongo-app.md --- aspnetcore/tutorials/first-mongo-app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/tutorials/first-mongo-app.md b/aspnetcore/tutorials/first-mongo-app.md index b678367382d4..826e8a963517 100644 --- a/aspnetcore/tutorials/first-mongo-app.md +++ b/aspnetcore/tutorials/first-mongo-app.md @@ -5,7 +5,7 @@ author: wadepickett description: This tutorial demonstrates how to create an ASP.NET Core web API using a MongoDB NoSQL database. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett -ms.custom: mvc, engagement-fy23 +ms.custom: mvc ms.date: 04/09/2025 uid: tutorials/first-mongo-app ---