@chill-sharp/ui-core 1.1.12 → 1.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -103
- package/fesm2022/chill-sharp-ui-core.mjs +2446 -2446
- package/fesm2022/chill-sharp-ui-core.mjs.map +1 -1
- package/lib/lib/chill-form.component.d.ts +1 -1
- package/package.json +3 -3
- package/service-worker/chill-sharp-service-worker.js +166 -166
- package/styles/core-theme.scss +1235 -1235
- package/.agents/skills/chillsharp-current-user-preferences/SKILL.md +0 -70
- package/.agents/skills/chillsharp-ui-template/SKILL.md +0 -18
- package/doc/AIAssistedDevelopment/README.md +0 -185
- package/doc/AttachmentModel/README.md +0 -173
- package/doc/AuthenticationModel/README.md +0 -213
- package/doc/AuthenticationModel/how-to-integreate-auth-minimal-api.md +0 -293
- package/doc/ChillSharpClient.md +0 -464
- package/doc/ClientGeneration/README.md +0 -172
- package/doc/ComplianceGuide/README.md +0 -178
- package/doc/Configuration/README.md +0 -94
- package/doc/CurrentUserPreferences.md +0 -114
- package/doc/DateTimePolicy/README.md +0 -154
- package/doc/DateTimeSerialization.md +0 -423
- package/doc/Endpoints.md +0 -260
- package/doc/HowTo/01-simple-blog-sqlite.md +0 -153
- package/doc/HowTo/02-blog-schema-labels.md +0 -140
- package/doc/HowTo/03-authentication.md +0 -218
- package/doc/HowTo/04-blog-posts-one-to-many.md +0 -194
- package/doc/HowTo/05-docker-env-variables.md +0 -274
- package/doc/HowTo/06-chunk-transactions-autocomplete.md +0 -196
- package/doc/Mcp/ChatGPT.md +0 -291
- package/doc/Mcp/README.md +0 -799
- package/doc/MenuGuide/README.md +0 -49
- package/doc/ModelPreparation.md +0 -255
- package/doc/PermissionModel/README.md +0 -277
- package/doc/README.md +0 -228
- package/doc/ReferenceExistence.md +0 -130
- package/doc/RegisterContext.md +0 -217
- package/doc/UiCore/CRUD.md +0 -170
- package/doc/UiCore/README.md +0 -13
- package/doc/ValidationModel/README.md +0 -117
- package/doc/it/AIAssistedDevelopment/README.md +0 -185
- package/doc/it/AttachmentModel/README.md +0 -173
- package/doc/it/AuthenticationModel/README.md +0 -171
- package/doc/it/AuthenticationModel/how-to-integreate-auth-minimal-api.md +0 -292
- package/doc/it/ChillSharpClient.md +0 -464
- package/doc/it/ClientGeneration/README.md +0 -152
- package/doc/it/ComplianceGuide/README.md +0 -178
- package/doc/it/Configuration/README.md +0 -94
- package/doc/it/CurrentUserPreferences.md +0 -114
- package/doc/it/DateTimePolicy/README.md +0 -154
- package/doc/it/DateTimeSerialization.md +0 -423
- package/doc/it/Endpoints.md +0 -260
- package/doc/it/HowTo/01-simple-blog-sqlite.md +0 -152
- package/doc/it/HowTo/02-blog-schema-labels.md +0 -139
- package/doc/it/HowTo/03-authentication.md +0 -221
- package/doc/it/HowTo/04-blog-posts-one-to-many.md +0 -193
- package/doc/it/HowTo/05-docker-env-variables.md +0 -268
- package/doc/it/HowTo/06-chunk-transactions-autocomplete.md +0 -196
- package/doc/it/Mcp/ChatGPT.md +0 -291
- package/doc/it/Mcp/README.md +0 -799
- package/doc/it/MenuGuide/README.md +0 -49
- package/doc/it/ModelPreparation.md +0 -254
- package/doc/it/PermissionModel/README.md +0 -190
- package/doc/it/README.md +0 -172
- package/doc/it/ReferenceExistence.md +0 -130
- package/doc/it/RegisterContext.md +0 -218
- package/doc/it/UiCore/CRUD.md +0 -170
- package/doc/it/UiCore/README.md +0 -13
- package/doc/it/ValidationModel/README.md +0 -117
- package/template-customization/upgrade.ps1.template +0 -342
- package/template-customization/upgrade.sh.template +0 -271
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# HOW-TO: API Blog Semplice Su SQLite
|
|
2
|
-
|
|
3
|
-
Versione originale in inglese: [English](../../HowTo/01-simple-blog-sqlite.md)
|
|
4
|
-
|
|
5
|
-
Questo esempio mostra la configurazione ChillSharp minima ma utile: una entita `Blog`, un contesto EF Core SQLite e una API ChillSharp senza testi label di schema negli attributi `ChillEntity` o `ChillProperty`.
|
|
6
|
-
|
|
7
|
-
## Obiettivo
|
|
8
|
-
|
|
9
|
-
Costruire una API minima che possa creare e leggere entita `Blog` tramite ChillSharp.
|
|
10
|
-
|
|
11
|
-
## 1. Definire L'Entita
|
|
12
|
-
|
|
13
|
-
Usa le versioni senza parametri di `ChillEntity` e `ChillProperty` quando non vuoi ancora fornire testi di schema.
|
|
14
|
-
|
|
15
|
-
```csharp
|
|
16
|
-
using ChillSharp.Annotations;
|
|
17
|
-
using ChillSharp.EF;
|
|
18
|
-
using System.ComponentModel.DataAnnotations;
|
|
19
|
-
|
|
20
|
-
namespace MyBlogApp.Model;
|
|
21
|
-
|
|
22
|
-
[ChillEntity]
|
|
23
|
-
public class Blog : ChillEntity
|
|
24
|
-
{
|
|
25
|
-
[Key]
|
|
26
|
-
public override Guid Guid { get; set; }
|
|
27
|
-
|
|
28
|
-
[ChillProperty]
|
|
29
|
-
public string Name { get; set; } = string.Empty;
|
|
30
|
-
|
|
31
|
-
[ChillProperty]
|
|
32
|
-
public string? Url { get; set; }
|
|
33
|
-
|
|
34
|
-
public override string GetLabel(IChillContext context) => Name;
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## 2. Definire Una Query
|
|
39
|
-
|
|
40
|
-
`Find` basta per caricare una sola entita tramite `Guid`, ma un tipo query resta utile quando vuoi filtri e proiezioni normali.
|
|
41
|
-
|
|
42
|
-
```csharp
|
|
43
|
-
using ChillSharp.Annotations;
|
|
44
|
-
using ChillSharp.EF;
|
|
45
|
-
|
|
46
|
-
namespace MyBlogApp.Query;
|
|
47
|
-
|
|
48
|
-
[ChillEntity]
|
|
49
|
-
public class BlogQuery : ChillQuery
|
|
50
|
-
{
|
|
51
|
-
[ChillProperty]
|
|
52
|
-
public string? Name { get; set; }
|
|
53
|
-
|
|
54
|
-
public override IQueryable<IChillEntity> OnQuery(IChillContext context)
|
|
55
|
-
{
|
|
56
|
-
var db = (BloggingContext)context;
|
|
57
|
-
var query = db.Blogs.AsQueryable();
|
|
58
|
-
|
|
59
|
-
if (Guid.HasValue)
|
|
60
|
-
query = query.Where(x => x.Guid == Guid.Value);
|
|
61
|
-
|
|
62
|
-
if (!string.IsNullOrWhiteSpace(Name))
|
|
63
|
-
query = query.Where(x => x.Name.Contains(Name));
|
|
64
|
-
|
|
65
|
-
return query;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## 3. Creare Il Contesto SQLite
|
|
71
|
-
|
|
72
|
-
Il contesto deve implementare `IChillContext` e restituire il prefisso namespace usato dai tipi model e query.
|
|
73
|
-
|
|
74
|
-
```csharp
|
|
75
|
-
using Microsoft.EntityFrameworkCore;
|
|
76
|
-
using MyBlogApp.Model;
|
|
77
|
-
|
|
78
|
-
namespace MyBlogApp;
|
|
79
|
-
|
|
80
|
-
public class BloggingContext : DbContext, IChillContext
|
|
81
|
-
{
|
|
82
|
-
public DbSet<Blog> Blogs => Set<Blog>();
|
|
83
|
-
|
|
84
|
-
public BloggingContext(DbContextOptions<BloggingContext> options) : base(options)
|
|
85
|
-
{
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public string GetChillTypePrefix() => "MyBlogApp";
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## 4. Registrare ChillSharp
|
|
93
|
-
|
|
94
|
-
```csharp
|
|
95
|
-
using ChillSharp.Api;
|
|
96
|
-
using Microsoft.EntityFrameworkCore;
|
|
97
|
-
|
|
98
|
-
var builder = WebApplication.CreateBuilder(args);
|
|
99
|
-
|
|
100
|
-
builder.Services.AddDbContext<BloggingContext>(options =>
|
|
101
|
-
options.UseSqlite("Data Source=blogging.db"));
|
|
102
|
-
|
|
103
|
-
builder.Services.AddChillApi<BloggingContext>();
|
|
104
|
-
|
|
105
|
-
var app = builder.Build();
|
|
106
|
-
|
|
107
|
-
using (var scope = app.Services.CreateScope())
|
|
108
|
-
{
|
|
109
|
-
var db = scope.ServiceProvider.GetRequiredService<BloggingContext>();
|
|
110
|
-
db.Database.EnsureCreated();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
app.MapChillApi();
|
|
114
|
-
app.Run();
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## 5. Creare E Leggere Un Blog Con `ChillSharpClient`
|
|
118
|
-
|
|
119
|
-
```csharp
|
|
120
|
-
using ChillSharp.Client;
|
|
121
|
-
using ChillSharp.Client.Dto;
|
|
122
|
-
|
|
123
|
-
var client = new ChillSharpClient("http://localhost:5000/api/chill");
|
|
124
|
-
|
|
125
|
-
var blog = new ChillDtoEntity
|
|
126
|
-
{
|
|
127
|
-
ChillType = "Model.Blog",
|
|
128
|
-
Guid = Guid.NewGuid()
|
|
129
|
-
};
|
|
130
|
-
blog.Properties["Name"] = "SQLite Notes";
|
|
131
|
-
blog.Properties["Url"] = "https://example.local/sqlite-notes";
|
|
132
|
-
|
|
133
|
-
var created = client.Create(blog);
|
|
134
|
-
|
|
135
|
-
var query = new ChillDtoQuery
|
|
136
|
-
{
|
|
137
|
-
ChillType = "Query.BlogQuery"
|
|
138
|
-
};
|
|
139
|
-
query.Properties["Guid"] = created.Guid;
|
|
140
|
-
query.ResultProperties = ChillDtoProperty.Build("Guid", "Name", "Url");
|
|
141
|
-
|
|
142
|
-
var result = client.Query(query);
|
|
143
|
-
var loadedBlog = result.Results.Single();
|
|
144
|
-
Console.WriteLine($"{loadedBlog.GetString("Name")} -> {loadedBlog.GetString("Url")}");
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Note
|
|
148
|
-
|
|
149
|
-
- `Model.Blog` e `Query.BlogQuery` sono nomi tipo brevi. ChillSharp li espande usando `GetChillTypePrefix()`.
|
|
150
|
-
- Con attributi senza parametri, i metadati schema fanno fallback ai nomi CLR di tipo e proprieta.
|
|
151
|
-
|
|
152
|
-
Esempio successivo: [Aggiungere label di schema e leggerle tramite ChillSharp](02-blog-schema-labels.md)
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
# HOW-TO: Aggiungere Label Di Schema Al Blog E Leggerle
|
|
2
|
-
|
|
3
|
-
Versione originale in inglese: [English](../../HowTo/02-blog-schema-labels.md)
|
|
4
|
-
|
|
5
|
-
Questo esempio aggiorna il modello `Blog` precedente aggiungendo testi di schema a `ChillEntity` e `ChillProperty`, poi mostra come leggere quelle label.
|
|
6
|
-
|
|
7
|
-
## Obiettivo
|
|
8
|
-
|
|
9
|
-
Decorare il modello con metadati di schema e recuperarli tramite i servizi schema di ChillSharp.
|
|
10
|
-
|
|
11
|
-
## 1. Aggiungere Label A Entita E Proprieta
|
|
12
|
-
|
|
13
|
-
```csharp
|
|
14
|
-
using ChillSharp.Annotations;
|
|
15
|
-
using ChillSharp.EF;
|
|
16
|
-
using System.ComponentModel.DataAnnotations;
|
|
17
|
-
|
|
18
|
-
namespace MyBlogApp.Model;
|
|
19
|
-
|
|
20
|
-
[ChillEntity(
|
|
21
|
-
UniquePropertyKeyString: "4E16F6C0-6B95-4D67-98BC-9F4D0D63EAF1",
|
|
22
|
-
PrimaryLanguageLabel: "Blog",
|
|
23
|
-
SecondaryLanguageLabel: "Blog")]
|
|
24
|
-
public class Blog : ChillEntity
|
|
25
|
-
{
|
|
26
|
-
[Key]
|
|
27
|
-
public override Guid Guid { get; set; }
|
|
28
|
-
|
|
29
|
-
[ChillProperty(
|
|
30
|
-
UniquePropertyKeyString: "50B1BB6C-D794-41E4-A85C-D4F9D7A6FA7E",
|
|
31
|
-
PrimaryLanguageLabel: "Blog name",
|
|
32
|
-
SecondaryLanguageLabel: "Nome blog")]
|
|
33
|
-
public string Name { get; set; } = string.Empty;
|
|
34
|
-
|
|
35
|
-
[ChillProperty(
|
|
36
|
-
UniquePropertyKeyString: "A18E7754-D8F7-45FE-B8A8-EA762A4EC9E6",
|
|
37
|
-
PrimaryLanguageLabel: "Blog url",
|
|
38
|
-
SecondaryLanguageLabel: "Url blog")]
|
|
39
|
-
public string? Url { get; set; }
|
|
40
|
-
|
|
41
|
-
public override string GetLabel(IChillContext context) => Name;
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## 2. Abilitare La Persistenza Dello Schema
|
|
46
|
-
|
|
47
|
-
Per esporre metadati schema tramite `get-schema`, il contesto EF Core deve anche implementare `IChillSchemaDbContext`, aggiungere il modello schema e registrare `AddChillSchema<TContext>()`.
|
|
48
|
-
|
|
49
|
-
```csharp
|
|
50
|
-
using ChillSharp.Schema;
|
|
51
|
-
using ChillSharp.Schema.Model;
|
|
52
|
-
using Microsoft.EntityFrameworkCore;
|
|
53
|
-
using MyBlogApp.Model;
|
|
54
|
-
|
|
55
|
-
namespace MyBlogApp;
|
|
56
|
-
|
|
57
|
-
public class BloggingContext : DbContext, IChillContext, IChillSchemaDbContext
|
|
58
|
-
{
|
|
59
|
-
public DbSet<Blog> Blogs => Set<Blog>();
|
|
60
|
-
public DbSet<ChillSchemaEntry> SchemaEntries => Set<ChillSchemaEntry>();
|
|
61
|
-
|
|
62
|
-
public BloggingContext(DbContextOptions<BloggingContext> options) : base(options)
|
|
63
|
-
{
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public string GetChillTypePrefix() => "MyBlogApp";
|
|
67
|
-
|
|
68
|
-
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
69
|
-
{
|
|
70
|
-
base.OnModelCreating(modelBuilder);
|
|
71
|
-
modelBuilder.AddChillSchemaModel();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Registra il servizio schema insieme all'API:
|
|
77
|
-
|
|
78
|
-
```csharp
|
|
79
|
-
using ChillSharp.Api;
|
|
80
|
-
using ChillSharp.Schema;
|
|
81
|
-
using Microsoft.EntityFrameworkCore;
|
|
82
|
-
|
|
83
|
-
var builder = WebApplication.CreateBuilder(args);
|
|
84
|
-
|
|
85
|
-
builder.Services.AddDbContext<BloggingContext>(options =>
|
|
86
|
-
options.UseSqlite("Data Source=blogging.db"));
|
|
87
|
-
|
|
88
|
-
builder.Services.AddChillApi<BloggingContext>();
|
|
89
|
-
builder.Services.AddChillSchema<BloggingContext>();
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## 3. Leggere I Metadati Di Schema Da Un Client
|
|
93
|
-
|
|
94
|
-
`ChillSharpClient.GetSchema(...)` restituisce metadati proprieta generati dal modello decorato.
|
|
95
|
-
|
|
96
|
-
```csharp
|
|
97
|
-
using ChillSharp.Client;
|
|
98
|
-
|
|
99
|
-
var client = new ChillSharpClient("http://localhost:5000/api/chill");
|
|
100
|
-
var schema = client.GetSchema("Model.Blog", "default");
|
|
101
|
-
|
|
102
|
-
var nameProperty = schema?.Properties.Single(x => x.Name == "Name");
|
|
103
|
-
var urlProperty = schema?.Properties.Single(x => x.Name == "Url");
|
|
104
|
-
|
|
105
|
-
Console.WriteLine(nameProperty?.DisplayName); // Blog name
|
|
106
|
-
Console.WriteLine(urlProperty?.DisplayName); // Blog url
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## 4. Leggere Il Nome Visualizzato Dell'Entita Sul Server
|
|
110
|
-
|
|
111
|
-
La `ChillSharp.Dto.ChillDtoSchema` lato server contiene anche il `DisplayName` dell'entita, popolato da `ChillEntityAttribute.PrimaryLanguageLabel`.
|
|
112
|
-
|
|
113
|
-
```csharp
|
|
114
|
-
using ChillSharp;
|
|
115
|
-
|
|
116
|
-
public class SchemaDebugService
|
|
117
|
-
{
|
|
118
|
-
private readonly IChillDtoEngine _dtoEngine;
|
|
119
|
-
|
|
120
|
-
public SchemaDebugService(IChillDtoEngine dtoEngine)
|
|
121
|
-
{
|
|
122
|
-
_dtoEngine = dtoEngine;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
public string? GetBlogSchemaDisplayName()
|
|
126
|
-
{
|
|
127
|
-
var schema = _dtoEngine.GetSchema("Model.Blog", "default");
|
|
128
|
-
return schema?.DisplayName;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Note
|
|
134
|
-
|
|
135
|
-
- `DisplayName` della proprieta viene da `ChillPropertyAttribute.PrimaryLanguageLabel`.
|
|
136
|
-
- `DisplayName` dell'entita viene da `ChillEntityAttribute.PrimaryLanguageLabel`.
|
|
137
|
-
- Se poi chiami `SetSchema(...)`, i valori schema persistiti possono sovrascrivere i default generati per un dato `ChillType` e `ChillViewCode`.
|
|
138
|
-
|
|
139
|
-
Esempio successivo: [Usare l'autenticazione con ChillSharp](03-authentication.md)
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
# HOW-TO: Usare L'Autenticazione Con ChillSharp
|
|
2
|
-
|
|
3
|
-
Versione originale in inglese: [English](../../HowTo/03-authentication.md)
|
|
4
|
-
|
|
5
|
-
Questo esempio mostra la configurazione di autenticazione minima ma utile per una API ChillSharp: proteggere l'API, abilitare il modulo auth, registrare un account, fare login e lasciare che `ChillSharpClient` riusi e rinnovi i token automaticamente.
|
|
6
|
-
|
|
7
|
-
## Obiettivo
|
|
8
|
-
|
|
9
|
-
Esporre una API ChillSharp protetta basata su ASP.NET Core Identity e autenticarsi con `ChillSharpClient`.
|
|
10
|
-
|
|
11
|
-
## 1. Usare Un Contesto Che Supporti Identity E ChillSharp Auth
|
|
12
|
-
|
|
13
|
-
Il contesto deve supportare il normale modello ChillSharp e le tabelle auth.
|
|
14
|
-
|
|
15
|
-
```csharp
|
|
16
|
-
using ChillSharp;
|
|
17
|
-
using ChillSharp.Auth;
|
|
18
|
-
using Microsoft.AspNetCore.Identity;
|
|
19
|
-
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
|
20
|
-
using Microsoft.EntityFrameworkCore;
|
|
21
|
-
|
|
22
|
-
namespace MyBlogApp;
|
|
23
|
-
|
|
24
|
-
public class BloggingContext : IdentityDbContext<IdentityUser>, IChillContext, IChillAuthDbContext
|
|
25
|
-
{
|
|
26
|
-
public BloggingContext(DbContextOptions<BloggingContext> options) : base(options)
|
|
27
|
-
{
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public string GetChillTypePrefix() => "MyBlogApp";
|
|
31
|
-
|
|
32
|
-
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
33
|
-
{
|
|
34
|
-
base.OnModelCreating(modelBuilder);
|
|
35
|
-
modelBuilder.AddChillAuthModel();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## 2. Registrare Identity, Authentication E I Servizi Auth ChillSharp
|
|
41
|
-
|
|
42
|
-
Proteggi la normale ChillSharp API e aggiungi sopra gli endpoint auth.
|
|
43
|
-
|
|
44
|
-
```csharp
|
|
45
|
-
using ChillSharp.Api;
|
|
46
|
-
using ChillSharp.Auth;
|
|
47
|
-
using ChillSharp.Auth.Api;
|
|
48
|
-
using Microsoft.AspNetCore.Identity;
|
|
49
|
-
using Microsoft.EntityFrameworkCore;
|
|
50
|
-
|
|
51
|
-
var builder = WebApplication.CreateBuilder(args);
|
|
52
|
-
|
|
53
|
-
builder.Services.AddDbContext<BloggingContext>(options =>
|
|
54
|
-
options.UseSqlite("Data Source=blogging-auth.db"));
|
|
55
|
-
|
|
56
|
-
builder.Services.AddIdentityCore<IdentityUser>()
|
|
57
|
-
.AddEntityFrameworkStores<BloggingContext>()
|
|
58
|
-
.AddSignInManager()
|
|
59
|
-
.AddDefaultTokenProviders();
|
|
60
|
-
|
|
61
|
-
builder.Services.AddAuthentication(ChillAuthIdentityDefaults.AuthenticationScheme)
|
|
62
|
-
.AddChillAuthBearer();
|
|
63
|
-
|
|
64
|
-
builder.Services.AddAuthorization();
|
|
65
|
-
|
|
66
|
-
builder.Services.AddChillApi<BloggingContext>(options =>
|
|
67
|
-
{
|
|
68
|
-
options.ProtectedApi = true;
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
builder.Services.AddChillAuthIdentityApi<BloggingContext, IdentityUser>(options =>
|
|
72
|
-
{
|
|
73
|
-
options.ReturnPasswordResetTokensInResponse = true;
|
|
74
|
-
options.InitializeRootUserOnStartup = true;
|
|
75
|
-
options.CreateChillAuthUserForRoot = true;
|
|
76
|
-
options.RootUserName = "root";
|
|
77
|
-
options.RootPassword = "Pass123$";
|
|
78
|
-
options.RootEmail = "root@example.com";
|
|
79
|
-
options.RootDisplayName = "Root Administrator";
|
|
80
|
-
});
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Quando `CreateChillAuthUserForRoot = true`, all'avvio viene creato anche il relativo `AuthUser` ChillSharp e `CanManagePermissions = true` viene impostato per quell'utente root.
|
|
84
|
-
|
|
85
|
-
Puoi fornire gli stessi valori di bootstrap anche tramite variabili d'ambiente invece di hardcodarli:
|
|
86
|
-
|
|
87
|
-
```text
|
|
88
|
-
CHILLSHARP_AUTH_ROOT_USERNAME=root
|
|
89
|
-
CHILLSHARP_AUTH_ROOT_PASSWORD=Pass123$
|
|
90
|
-
CHILLSHARP_AUTH_ROOT_EMAIL=root@example.com
|
|
91
|
-
CHILLSHARP_AUTH_ROOT_DISPLAY_NAME=Root Administrator
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## 3. Abilitare Il Middleware E Mappare L'API
|
|
95
|
-
|
|
96
|
-
`MapChillApi()` espone sia gli endpoint normali ChillSharp sia quelli auth una volta registrati i servizi auth.
|
|
97
|
-
|
|
98
|
-
```csharp
|
|
99
|
-
var app = builder.Build();
|
|
100
|
-
|
|
101
|
-
app.UseAuthentication();
|
|
102
|
-
app.UseAuthorization();
|
|
103
|
-
|
|
104
|
-
using (var scope = app.Services.CreateScope())
|
|
105
|
-
{
|
|
106
|
-
var db = scope.ServiceProvider.GetRequiredService<BloggingContext>();
|
|
107
|
-
db.Database.EnsureCreated();
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
app.MapChillApi();
|
|
111
|
-
app.Run();
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## 4. Usare L'Utente Root Per Gestire I Permessi
|
|
115
|
-
|
|
116
|
-
L'inizializzatore root-user e la via piu semplice di bootstrap per un sistema protetto nuovo, perche l'utente auth ChillSharp collegato viene creato con la gestione permessi abilitata.
|
|
117
|
-
|
|
118
|
-
```csharp
|
|
119
|
-
var rootClient = new ChillSharpClient("http://localhost:5000/api/chill");
|
|
120
|
-
|
|
121
|
-
var rootLogin = rootClient.LoginAuthAccount(new LoginAuthIdentityRequest
|
|
122
|
-
{
|
|
123
|
-
UserNameOrEmail = "root",
|
|
124
|
-
Password = "Pass123$"
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
var authUsers = rootClient.GetAuthUsers();
|
|
128
|
-
Console.WriteLine(authUsers.Count);
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Quel login puo chiamare endpoint di gestione auth come utenti, ruoli e regole di permesso perche l'`AuthUser` root generato ha `CanManagePermissions = true`.
|
|
132
|
-
|
|
133
|
-
## 5. Registrare Il Primo Account Normale
|
|
134
|
-
|
|
135
|
-
Crea il client con il normale Chill base URL. Le chiamate auth passano automaticamente da `/api/chill` a `/api/chill-auth`.
|
|
136
|
-
|
|
137
|
-
```csharp
|
|
138
|
-
using ChillSharp.Auth.Contracts;
|
|
139
|
-
using ChillSharp.Client;
|
|
140
|
-
|
|
141
|
-
var client = new ChillSharpClient("http://localhost:5000/api/chill");
|
|
142
|
-
|
|
143
|
-
var registerResponse = client.RegisterAuthAccount(new RegisterAuthIdentityRequest
|
|
144
|
-
{
|
|
145
|
-
UserName = "admin",
|
|
146
|
-
Email = "admin@example.com",
|
|
147
|
-
Password = "Pass123$",
|
|
148
|
-
DisplayName = "Administrator",
|
|
149
|
-
DisplayCultureName = "it-IT",
|
|
150
|
-
CreateChillAuthUser = true
|
|
151
|
-
});
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Dopo una registrazione riuscita, il client salva internamente access token e refresh token restituiti.
|
|
155
|
-
|
|
156
|
-
Se `DisplayCultureName` viene fornito e `CreateChillAuthUser = true`, il relativo `AuthUser` viene inizializzato con valori derivati dalla cultura per:
|
|
157
|
-
|
|
158
|
-
- `DisplayTimeZone`
|
|
159
|
-
- `DisplayDateFormat`
|
|
160
|
-
- `DisplayNumberFormat`
|
|
161
|
-
|
|
162
|
-
Per esempio, `it-IT` tipicamente produce preset come:
|
|
163
|
-
|
|
164
|
-
- `DisplayTimeZone = "W. Europe Standard Time"`
|
|
165
|
-
- `DisplayDateFormat = "DD/MM/YYYY"`
|
|
166
|
-
- `DisplayNumberFormat = "1.000,00"`
|
|
167
|
-
|
|
168
|
-
Questi sono preset server-side e possono essere modificati in seguito tramite la gestione utenti auth.
|
|
169
|
-
|
|
170
|
-
## 6. Fare Login Esplicito
|
|
171
|
-
|
|
172
|
-
Se l'account esiste gia, fai login con lo stesso `ChillSharpClient`.
|
|
173
|
-
|
|
174
|
-
```csharp
|
|
175
|
-
var loginResponse = client.LoginAuthAccount(new LoginAuthIdentityRequest
|
|
176
|
-
{
|
|
177
|
-
UserNameOrEmail = "admin",
|
|
178
|
-
Password = "Pass123$"
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
## 7. Chiamare Endpoint Protetti
|
|
183
|
-
|
|
184
|
-
Una volta autenticato, lo stesso client puo chiamare gli endpoint ChillSharp protetti.
|
|
185
|
-
|
|
186
|
-
```csharp
|
|
187
|
-
using ChillSharp.Client.Dto;
|
|
188
|
-
|
|
189
|
-
var query = new ChillDtoQuery
|
|
190
|
-
{
|
|
191
|
-
ChillType = "Query.BlogQuery"
|
|
192
|
-
};
|
|
193
|
-
query.ResultProperties = ChillDtoProperty.Build("Guid", "Name");
|
|
194
|
-
|
|
195
|
-
var result = client.Query(query);
|
|
196
|
-
Console.WriteLine(result.Results.Count);
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## 8. Lasciare Che Il Client Rinnovi I Token Automaticamente
|
|
200
|
-
|
|
201
|
-
Non devi allegare manualmente il bearer token a ogni richiesta. Se il client ha gia un refresh token, le chiamate autenticate rinnovano l'access token quando serve.
|
|
202
|
-
|
|
203
|
-
```csharp
|
|
204
|
-
var roles = client.GetAuthRoles();
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
Puoi anche fare refresh esplicito:
|
|
208
|
-
|
|
209
|
-
```csharp
|
|
210
|
-
var refreshed = client.RefreshAuthAccount();
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
## Note
|
|
214
|
-
|
|
215
|
-
- Usa `options.ProtectedApi = true` su `AddChillApi<TContext>(...)` se gli endpoint ChillSharp devono richiedere autenticazione.
|
|
216
|
-
- L'utente root creato da `AddChillAuthIdentityApi(...)` e il percorso bootstrap amministrativo. Quando `CreateChillAuthUserForRoot = true`, il relativo `AuthUser` ChillSharp viene creato con `CanManagePermissions = true`.
|
|
217
|
-
- `CreateChillAuthUser = true` crea l'`AuthUser` ChillSharp collegato, ma non concede automaticamente permessi amministrativi.
|
|
218
|
-
- `DisplayCultureName` in registrazione preimposta `DisplayTimeZone`, `DisplayDateFormat` e `DisplayNumberFormat` per il relativo `AuthUser`.
|
|
219
|
-
- In produzione, inizializza il primo amministratore in modo deliberato, ad esempio con root-user initialization o un flusso trusted in fase di installazione.
|
|
220
|
-
|
|
221
|
-
Esempio successivo: [Creare un'immagine Docker e configurarla con variabili d'ambiente](05-docker-env-variables.md)
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
# HOW-TO: Gestire Una Relazione Blog-Posts Uno-a-Molti
|
|
2
|
-
|
|
3
|
-
Versione originale in inglese: [English](../../HowTo/04-blog-posts-one-to-many.md)
|
|
4
|
-
|
|
5
|
-
Questo esempio estende il modello blog con i post e mostra come caricare un blog insieme ai suoi post in una singola chiamata `ChillSharpClient.Query(...)`.
|
|
6
|
-
|
|
7
|
-
## Obiettivo
|
|
8
|
-
|
|
9
|
-
Modellare una relazione uno-a-molti `Blog` -> `Posts` e proiettare la collezione annidata dal client ChillSharp.
|
|
10
|
-
|
|
11
|
-
## 1. Definire Le Entita
|
|
12
|
-
|
|
13
|
-
```csharp
|
|
14
|
-
using ChillSharp.Annotations;
|
|
15
|
-
using ChillSharp.EF;
|
|
16
|
-
using System.ComponentModel.DataAnnotations;
|
|
17
|
-
|
|
18
|
-
namespace MyBlogApp.Model;
|
|
19
|
-
|
|
20
|
-
[ChillEntity]
|
|
21
|
-
public class Blog : ChillEntity
|
|
22
|
-
{
|
|
23
|
-
[Key]
|
|
24
|
-
public override Guid Guid { get; set; }
|
|
25
|
-
|
|
26
|
-
[ChillProperty]
|
|
27
|
-
public string Name { get; set; } = string.Empty;
|
|
28
|
-
|
|
29
|
-
[ChillProperty]
|
|
30
|
-
public string? Url { get; set; }
|
|
31
|
-
|
|
32
|
-
[ChillProperty]
|
|
33
|
-
public ICollection<Post>? Posts { get; set; }
|
|
34
|
-
|
|
35
|
-
public override string GetLabel(IChillContext context) => Name;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
[ChillEntity]
|
|
39
|
-
public class Post : ChillEntity
|
|
40
|
-
{
|
|
41
|
-
[Key]
|
|
42
|
-
public override Guid Guid { get; set; }
|
|
43
|
-
|
|
44
|
-
[ChillProperty]
|
|
45
|
-
public Blog? Blog { get; set; }
|
|
46
|
-
|
|
47
|
-
[ChillProperty]
|
|
48
|
-
public DateTime? CreatedAt { get; set; }
|
|
49
|
-
|
|
50
|
-
[ChillProperty]
|
|
51
|
-
public string Title { get; set; } = string.Empty;
|
|
52
|
-
|
|
53
|
-
[ChillProperty]
|
|
54
|
-
public string Content { get; set; } = string.Empty;
|
|
55
|
-
|
|
56
|
-
public override void OnCreate(IChillContext context)
|
|
57
|
-
{
|
|
58
|
-
base.OnCreate(context);
|
|
59
|
-
CreatedAt = DateTime.UtcNow;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
public override string GetLabel(IChillContext context) => Title;
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## 2. Aggiungere Entrambi I Set Al Contesto
|
|
67
|
-
|
|
68
|
-
```csharp
|
|
69
|
-
using Microsoft.EntityFrameworkCore;
|
|
70
|
-
using MyBlogApp.Model;
|
|
71
|
-
|
|
72
|
-
namespace MyBlogApp;
|
|
73
|
-
|
|
74
|
-
public class BloggingContext : DbContext, IChillContext
|
|
75
|
-
{
|
|
76
|
-
public DbSet<Blog> Blogs => Set<Blog>();
|
|
77
|
-
public DbSet<Post> Posts => Set<Post>();
|
|
78
|
-
|
|
79
|
-
public BloggingContext(DbContextOptions<BloggingContext> options) : base(options)
|
|
80
|
-
{
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
public string GetChillTypePrefix() => "MyBlogApp";
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## 3. Definire Una Query Per I Blog
|
|
88
|
-
|
|
89
|
-
```csharp
|
|
90
|
-
using ChillSharp.Annotations;
|
|
91
|
-
using ChillSharp.EF;
|
|
92
|
-
|
|
93
|
-
namespace MyBlogApp.Query;
|
|
94
|
-
|
|
95
|
-
[ChillEntity]
|
|
96
|
-
public class BlogQuery : ChillQuery
|
|
97
|
-
{
|
|
98
|
-
[ChillProperty]
|
|
99
|
-
public string? Name { get; set; }
|
|
100
|
-
|
|
101
|
-
public override IQueryable<IChillEntity> OnQuery(IChillContext context)
|
|
102
|
-
{
|
|
103
|
-
var db = (BloggingContext)context;
|
|
104
|
-
var query = db.Blogs.AsQueryable();
|
|
105
|
-
|
|
106
|
-
if (Guid.HasValue)
|
|
107
|
-
query = query.Where(x => x.Guid == Guid.Value);
|
|
108
|
-
|
|
109
|
-
if (!string.IsNullOrWhiteSpace(Name))
|
|
110
|
-
query = query.Where(x => x.Name.Contains(Name));
|
|
111
|
-
|
|
112
|
-
return query;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## 4. Creare Un Blog E Due Post
|
|
118
|
-
|
|
119
|
-
La relazione viene creata inviando il DTO padre `Blog` come proprieta `Blog` di ogni `Post`.
|
|
120
|
-
|
|
121
|
-
```csharp
|
|
122
|
-
using ChillSharp.Client;
|
|
123
|
-
using ChillSharp.Client.Dto;
|
|
124
|
-
|
|
125
|
-
var client = new ChillSharpClient("http://localhost:5000/api/chill");
|
|
126
|
-
|
|
127
|
-
var blog = new ChillDtoEntity
|
|
128
|
-
{
|
|
129
|
-
ChillType = "Model.Blog",
|
|
130
|
-
Guid = Guid.NewGuid()
|
|
131
|
-
};
|
|
132
|
-
blog.Properties["Name"] = "ChillSharp Blog";
|
|
133
|
-
blog.Properties["Url"] = "https://example.local/chillsharp-blog";
|
|
134
|
-
|
|
135
|
-
var createdBlog = client.Create(blog);
|
|
136
|
-
|
|
137
|
-
var firstPost = new ChillDtoEntity
|
|
138
|
-
{
|
|
139
|
-
ChillType = "Model.Post",
|
|
140
|
-
Guid = Guid.NewGuid()
|
|
141
|
-
};
|
|
142
|
-
firstPost.Properties["Title"] = "First post";
|
|
143
|
-
firstPost.Properties["Content"] = "Hello from ChillSharp";
|
|
144
|
-
firstPost.Properties["Blog"] = createdBlog.Mock();
|
|
145
|
-
client.Create(firstPost);
|
|
146
|
-
|
|
147
|
-
var secondPost = new ChillDtoEntity
|
|
148
|
-
{
|
|
149
|
-
ChillType = "Model.Post",
|
|
150
|
-
Guid = Guid.NewGuid()
|
|
151
|
-
};
|
|
152
|
-
secondPost.Properties["Title"] = "Second post";
|
|
153
|
-
secondPost.Properties["Content"] = "Nested queries are handy";
|
|
154
|
-
secondPost.Properties["Blog"] = createdBlog.Mock();
|
|
155
|
-
client.Create(secondPost);
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## 5. Caricare Un Blog Con I Suoi Post In Una Chiamata
|
|
159
|
-
|
|
160
|
-
Questa e la parte piu importante per una relazione uno-a-molti: la proiezione annidata viene descritta tramite `ChillDtoProperty.With(...)`, e la collezione restituita viene letta con `GetCollection(...)`.
|
|
161
|
-
|
|
162
|
-
```csharp
|
|
163
|
-
using ChillSharp.Client.Dto;
|
|
164
|
-
|
|
165
|
-
var query = new ChillDtoQuery
|
|
166
|
-
{
|
|
167
|
-
ChillType = "Query.BlogQuery"
|
|
168
|
-
};
|
|
169
|
-
query.Properties["Guid"] = createdBlog.Guid;
|
|
170
|
-
query.ResultProperties = ChillDtoProperty.Build(
|
|
171
|
-
"Guid",
|
|
172
|
-
"Name",
|
|
173
|
-
"Url",
|
|
174
|
-
ChillDtoProperty.With("Posts", "Guid", "Title", "CreatedAt"));
|
|
175
|
-
|
|
176
|
-
var queryResult = client.Query(query);
|
|
177
|
-
var loadedBlog = queryResult.Results.Single();
|
|
178
|
-
|
|
179
|
-
Console.WriteLine(loadedBlog.GetString("Name"));
|
|
180
|
-
|
|
181
|
-
foreach (var post in loadedBlog.GetCollection("Posts"))
|
|
182
|
-
{
|
|
183
|
-
Console.WriteLine(post.GetString("Title"));
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
## Cosa Ti Da Questo
|
|
188
|
-
|
|
189
|
-
- una chiamata HTTP per caricare l'entita padre e la collezione figlia
|
|
190
|
-
- un builder di proiezione fortemente tipizzato lato client
|
|
191
|
-
- gestione della relazione tramite DTO senza scrivere un controller dedicato per `Blog` o `Post`
|
|
192
|
-
|
|
193
|
-
Prossimo: [Torna all'indice della documentazione](../README.md)
|