Gestione appsetting x cliente - App WASM Blazor WASM/PWA - Configurazione AppSettings per più clienti Obiettivo Gestire pubblicazioni diverse della stessa app Blazor WebAssembly/PWA per più clienti, evitando di modificare manualmente appsettings.json dopo la pubblicazione. Nelle app Blazor WASM/PWA i file pubblicati vengono gestiti anche dal service worker e dal manifest degli asset: service-worker-assets.js Se si modifica manualmente un file statico dopo la pubblicazione, ad esempio appsettings.json , si possono creare problemi di cache, integrità o caricamento della PWA. La soluzione corretta è: 1. mantenere un appsettings.json comune 2. creare un file appsettings per ogni cliente 3. tenere i file cliente fuori da wwwroot 4. usare un profilo di pubblicazione per cliente 5. fare copiare al .csproj solo il file del cliente pubblicato 1. Struttura cartelle consigliata Nel progetto Blazor WASM, ad esempio Soluziona.Apps.Magazzino , usare questa struttura: Soluziona.Apps.Magazzino ├── SettingClienti │ ├── Comside │ │ └── appsettings.Comside.json │ └── Demo │ └── appsettings.Demo.json │ ├── Properties │ └── PublishProfiles │ ├── Comside.pubxml │ └── Demo.pubxml │ └── wwwroot ├── appsettings.json ├── appsettings.Development.json ├── index.html ├── manifest.webmanifest ├── service-worker.js └── ... Regola Dentro wwwroot devono rimanere solo: appsettings.json appsettings.Development.json I file dei clienti devono stare fuori da wwwroot , dentro: SettingClienti\\appsettings..json Esempio: SettingClienti\Comside\appsettings.Comside.json SettingClienti\Demo\appsettings.Demo.json Non mettere dentro wwwroot : appsettings.Comside.json appsettings.Demo.json altrimenti rischiano di essere pubblicati tutti insieme. 2. appsettings.json comune Il file: wwwroot\appsettings.json deve contenere solo i valori comuni a tutti i clienti. Esempio: { "App": { "NomeApp": "Liste di Carico", "SottoTitoloApp": "Gestione preparazione ordini", "Versione": "1.0.6", "Build": "2026.09.09.006", "Ambiente": "Production", "PaginaIniziale": "/calendario" }, "Api": { "TimeoutSecondi": 30 }, "Offline": {}, "SyncListeDiCarico": { "IntervalloSecondi": 30, "GiorniIndietro": 15, "GiorniAvanti": 15, "EseguiAllAvvio": true } } Nota In questo file può mancare: "BaseUrl" perché viene valorizzato dal file cliente, ad esempio: appsettings.Comside.json A runtime Blazor caricherà: appsettings.json + appsettings.Comside.json 3. appsettings.Development.json Il file: wwwroot\appsettings.Development.json viene usato per lo sviluppo locale. Esempio: { "App": { "IdApplicazione": "17630f17-7626-416f-961b-486fbd64fd4f", "CodiceApplicazione": "APPLISTEDICARICO", "CodiceAzienda": "3", "Ambiente": "Development" }, "Api": { "BaseUrl": "https://localhost:7021/", "TimeoutSecondi": 30 } } Questo file non deve essere pubblicato in produzione. 4. AppSettings per cliente Demo Percorso: SettingClienti\Demo\appsettings.Demo.json Contenuto: { "App": { "IdApplicazione": "17630f17-7626-416f-961b-486fbd64fd4f", "CodiceApplicazione": "APPLISTEDICARICO", "CodiceAzienda": "3", "Ambiente": "Production" }, "Api": { "BaseUrl": "https://soluzionacoreapi.soluziona.cloud:443/", "TimeoutSecondi": 30 } } Comside Percorso: SettingClienti\Comside\appsettings.Comside.json Contenuto: { "App": { "IdApplicazione": "90208117-20b4-446c-a771-42bce3fb63c5", "CodiceApplicazione": "ListeDiCarico", "CodiceAzienda": "59", "Ambiente": "Production" }, "Api": { "BaseUrl": "https://192.168.232.122:4433/", "TimeoutSecondi": 30 } } 5. Modifica del .csproj Aprire il file .csproj del progetto Blazor WASM, ad esempio: Soluziona.Apps.Magazzino.csproj La configurazione deve: 1. escludere SettingClienti dagli item automatici del SDK 2. escludere eventuali appsettings ambiente da wwwroot 3. copiare il file cliente corretto dentro wwwroot prima della build/publish 4. includere esplicitamente il file copiato come Content 5.1 Esclusione file cliente e appsettings ambiente Nel primo PropertyGroup aggiungere: $(DefaultItemExcludes);SettingClienti\**\*;wwwroot\appsettings.*.json Esempio: net10.0 enable enable true service-worker-assets.js $(DefaultItemExcludes);SettingClienti\**\*;wwwroot\appsettings.*.json Questa riga esclude: SettingClienti\... wwwroot\appsettings.Demo.json wwwroot\appsettings.Comside.json wwwroot\appsettings.Development.json Non esclude: wwwroot\appsettings.json perché il file comune deve sempre essere pubblicato. 5.2 Reincludere appsettings.Development.json Poiché wwwroot\appsettings.*.json viene escluso dagli item automatici, appsettings.Development.json va reincluso esplicitamente, ma senza pubblicarlo. PreserveNewest Never 5.3 Target per preparare l’appsettings cliente Aggiungere questo target prima di: PreserveNewest PreserveNewest 6. .csproj completo finale net10.0 enable enable true service-worker-assets.js $(DefaultItemExcludes);SettingClienti\**\*;wwwroot\appsettings.*.json Always PreserveNewest Never PreserveNewest PreserveNewest Nota importante per Git Il target copia automaticamente il file cliente dentro wwwroot . Esempio: SettingClienti\Comside\appsettings.Comside.json → wwwroot\appsettings.Comside.json Questo file in wwwroot è generato automaticamente e non deve essere committato. Aggiungere al .gitignore in fondo: # AppSettings cliente generati automaticamente dal publish **/wwwroot/appsettings.*.json # Mantiene versionato appsettings.Development.json !**/wwwroot/appsettings.Development.json wwwroot\appsettings.json non viene escluso da questa regola, quindi rimane versionato normalmente. 7. Profili di pubblicazione I profili vanno creati da Visual Studio con: Tasto destro sul progetto → Publish → New profile → Folder Dopo la creazione, modificare i file .pubxml . Profilo Demo Percorso: Properties\PublishProfiles\Demo.pubxml Contenuto: true false true Release Any CPU FileSystem C:\Repos\Pubblicati\AppListeDiCarico\Demo FileSystem <_TargetId>Folder Demo Profilo Comside Percorso: Properties\PublishProfiles\Comside.pubxml Contenuto: true false true Release Any CPU FileSystem C:\Repos\Pubblicati\AppListeDiCarico\Comside FileSystem <_TargetId>Folder Comside 8. Proprietà fondamentale: WasmApplicationEnvironmentName La riga più importante del profilo è questa: Comside oppure: Demo Questa proprietà decide quale ambiente Blazor deve usare. Esempio: WasmApplicationEnvironmentName = Comside → carica appsettings.json → carica appsettings.Comside.json WasmApplicationEnvironmentName = Demo → carica appsettings.json → carica appsettings.Demo.json Il valore deve combaciare esattamente con: nome cartella cliente nome file appsettings Esempio corretto: Comside → SettingClienti\Comside\appsettings.Comside.json Esempio errato: COMSIDE → SettingClienti\Comside\appsettings.Comside.json 9. Nota su App:Ambiente Dentro gli appsettings cliente si può lasciare: "Ambiente": "Production" Questo valore è una configurazione applicativa interna. Non decide quale file appsettings.*.json viene caricato. Il file caricato viene deciso da: Comside non da: "Ambiente": "Production"