Skip to content

Commit 1f99dc6

Browse files
committed
update first-mono-app to .NET 10
1 parent a28c16f commit 1f99dc6

12 files changed

Lines changed: 830 additions & 49 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
ASP.NET Core Identity adds user interface (UI) login functionality to ASP.NET Core web apps. To secure web APIs and SPAs, use one of the following:
2+
3+
* [Microsoft Entra ID](/azure/api-management/api-management-howto-protect-backend-with-aad)
4+
* [Duende Identity Server](https://docs.duendesoftware.com)
5+
6+
Duende Identity Server is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core. Duende Identity Server enables the following security features:
7+
8+
* Authentication as a Service (AaaS)
9+
* Single sign-on/off (SSO) over multiple application types
10+
* Access control for APIs
11+
* Federation Gateway
12+
13+
> [!IMPORTANT]
14+
> [Duende Software](https://duendesoftware.com/) might require you to pay a license fee for production use of Duende Identity Server.
15+
16+
For more information, see the [Duende Identity Server documentation (Duende Software website)](https://docs.duendesoftware.com).

aspnetcore/tutorials/first-mongo-app.md

Lines changed: 51 additions & 49 deletions
Large diffs are not rendered by default.

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

Lines changed: 518 additions & 0 deletions
Large diffs are not rendered by default.
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>net10.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.7" />
11+
<PackageReference Include="MongoDB.Driver" Version="3.8.0" />
12+
<PackageReference Include="NSwag.AspNetCore" Version="14.7.1" />
13+
</ItemGroup>
14+
15+
</Project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@BookStoreApi_HostAddress = https://localhost:56874
2+
3+
GET {{BookStoreApi_HostAddress}}/books
4+
5+
###
6+
7+
@id=string
8+
GET {{BookStoreApi_HostAddress}}/books/{{id}}
9+
10+
###
11+
12+
POST {{BookStoreApi_HostAddress}}/books
13+
Content-Type: application/json
14+
15+
{
16+
//Book
17+
}
18+
19+
###
20+
21+
DELETE {{BookStoreApi_HostAddress}}/books/{{id}}
22+
23+
###
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// <snippet_UsingSystemTextJsonSerialization>
2+
using System.Text.Json.Serialization;
3+
// </snippet_UsingSystemTextJsonSerialization>
4+
using MongoDB.Bson;
5+
using MongoDB.Bson.Serialization.Attributes;
6+
7+
namespace BookStoreApi.Models;
8+
9+
public class Book
10+
{
11+
[BsonId]
12+
[BsonRepresentation(BsonType.ObjectId)]
13+
public string? Id { get; set; }
14+
15+
// <snippet_BookName>
16+
[BsonElement("Name")]
17+
[JsonPropertyName("Name")]
18+
public string BookName { get; set; } = null!;
19+
// </snippet_BookName>
20+
21+
public decimal Price { get; set; }
22+
23+
public string Category { get; set; } = null!;
24+
25+
public string Author { get; set; } = null!;
26+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace BookStoreApi.Models;
2+
3+
public class BookStoreDatabaseSettings
4+
{
5+
public string ConnectionString { get; set; } = null!;
6+
7+
public string DatabaseName { get; set; } = null!;
8+
9+
public string BooksCollectionName { get; set; } = null!;
10+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// <snippet_UsingModels>
2+
using BookStoreApi.Models;
3+
// </snippet_UsingModels>
4+
// <snippet_UsingServices>
5+
using BookStoreApi.Services;
6+
// </snippet_UsingServices>
7+
8+
// <snippet_JsonOptions>
9+
// <snippet_BooksService>
10+
// <snippet_BookStoreDatabaseSettings>
11+
var builder = WebApplication.CreateBuilder(args);
12+
13+
// Add services to the container.
14+
builder.Services.Configure<BookStoreDatabaseSettings>(
15+
builder.Configuration.GetSection("BookStoreDatabase"));
16+
// </snippet_BookStoreDatabaseSettings>
17+
18+
builder.Services.AddSingleton<BooksService>();
19+
// </snippet_BooksService>
20+
21+
builder.Services.Configure<Microsoft.AspNetCore.Http.Json.JsonOptions>(options =>
22+
{
23+
options.SerializerOptions.PropertyNamingPolicy = null;
24+
});
25+
// </snippet_JsonOptions>
26+
27+
// Add services to the container.
28+
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
29+
builder.Services.AddOpenApi();
30+
31+
// <snippet_UseSwagger>
32+
var app = builder.Build();
33+
34+
if (app.Environment.IsDevelopment())
35+
{
36+
app.MapOpenApi();
37+
app.UseSwaggerUi(options =>
38+
{
39+
options.DocumentPath = "/openapi/v1.json";
40+
});
41+
}
42+
// </snippet_UseSwagger>
43+
44+
// <snippet_MapEndpoints>
45+
var booksGroup = app.MapGroup("/books");
46+
47+
booksGroup.MapGet("/", async (BooksService booksService) =>
48+
{
49+
var books = await booksService.GetAsync();
50+
return Results.Ok(books);
51+
});
52+
53+
booksGroup.MapGet("/{id:length(24)}", async (string id, BooksService booksService) =>
54+
{
55+
var book = await booksService.GetAsync(id);
56+
57+
return book is null ? Results.NotFound() : Results.Ok(book);
58+
});
59+
60+
booksGroup.MapPost("/", async (Book newBook, BooksService booksService) =>
61+
{
62+
await booksService.CreateAsync(newBook);
63+
64+
return Results.Created($"/books/{newBook.Id}", newBook);
65+
});
66+
67+
booksGroup.MapPut("/{id:length(24)}", async (string id, Book updatedBook, BooksService booksService) =>
68+
{
69+
var book = await booksService.GetAsync(id);
70+
71+
if (book is null)
72+
{
73+
return Results.NotFound();
74+
}
75+
76+
updatedBook.Id = book.Id;
77+
78+
await booksService.UpdateAsync(id, updatedBook);
79+
80+
return Results.NoContent();
81+
});
82+
83+
booksGroup.MapDelete("/{id:length(24)}", async (string id, BooksService booksService) =>
84+
{
85+
var book = await booksService.GetAsync(id);
86+
87+
if (book is null)
88+
{
89+
return Results.NotFound();
90+
}
91+
92+
await booksService.RemoveAsync(id);
93+
94+
return Results.NoContent();
95+
});
96+
// </snippet_MapEndpoints>
97+
98+
app.Run();
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// <snippet_File>
2+
using BookStoreApi.Models;
3+
using Microsoft.Extensions.Options;
4+
using MongoDB.Driver;
5+
6+
namespace BookStoreApi.Services;
7+
8+
// <snippet_ctor>
9+
public class BooksService(IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings)
10+
{
11+
private readonly IMongoCollection<Book> _booksCollection = new MongoClient(bookStoreDatabaseSettings.Value.ConnectionString)
12+
.GetDatabase(bookStoreDatabaseSettings.Value.DatabaseName)
13+
.GetCollection<Book>(bookStoreDatabaseSettings.Value.BooksCollectionName);
14+
// </snippet_ctor>
15+
16+
public async Task<List<Book>> GetAsync() =>
17+
await _booksCollection.Find(_ => true).ToListAsync();
18+
19+
public async Task<Book?> GetAsync(string id) =>
20+
await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync();
21+
22+
public async Task CreateAsync(Book newBook) =>
23+
await _booksCollection.InsertOneAsync(newBook);
24+
25+
public async Task UpdateAsync(string id, Book updatedBook) =>
26+
await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook);
27+
28+
public async Task RemoveAsync(string id) =>
29+
await _booksCollection.DeleteOneAsync(x => x.Id == id);
30+
}
31+
// </snippet_File>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)