01f78466df
- Aggiunta persistenza campi ODBC (OdbcDsnName, OdbcMode) in CredentialEntity - Creata migration EF Core per nuovi campi database - Aggiornato mapping credenziali per caricare/salvare dati ODBC - Creato OdbcDatabaseManager dedicato (bypass EF Core che non supporta ODBC) - Aggiornato DataConnectionFactory per usare OdbcDatabaseManager con connessioni ODBC - Fix auto-load DSN: sostituito @onchange con @bind-Value:after in dropdown tipo database - Fix test connessione SAP HANA: rimossa query SELECT 1 che causava errori sintassi - Implementati tutti i metodi IDatabaseManager in OdbcDatabaseManager - Supporto completo per discovery schema, tabelle e query ODBC Risolve problema DbContext non configurato per ODBC e abilita connessioni ODBC complete.
422 lines
13 KiB
Markdown
422 lines
13 KiB
Markdown
# Correzioni UI ODBC - Riepilogo
|
|
|
|
## 📋 Problemi Risolti
|
|
|
|
### ✅ Problema 1: Lista Driver Non Compilata Automaticamente
|
|
|
|
**Problema Originale**:
|
|
La lista dei driver ODBC richiedeva un click su "Aggiorna Lista" la prima volta.
|
|
|
|
**Soluzione Implementata**:
|
|
1. **ShowAddDatabaseModal()** - Modificato per essere asincrono e caricare automaticamente i dati ODBC:
|
|
```csharp
|
|
private async Task ShowAddDatabaseModal()
|
|
{
|
|
// ... inizializzazione ...
|
|
showDatabaseModal = true;
|
|
|
|
// Carica automaticamente se ODBC è selezionato
|
|
if (currentDatabaseCredential.DatabaseType == DatabaseType.Odbc)
|
|
{
|
|
await LoadOdbcData();
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **EditDatabaseCredential()** - Modificato per essere asincrono, caricare dati ODBC e ripristinare il driver selezionato:
|
|
```csharp
|
|
private async Task EditDatabaseCredential(DatabaseCredential credential)
|
|
{
|
|
// ... copia proprietà ...
|
|
currentDatabaseCredential.OdbcDsnName = credential.OdbcDsnName;
|
|
currentDatabaseCredential.OdbcMode = credential.OdbcMode;
|
|
currentDatabaseCredential.AdditionalParameters = credential.AdditionalParameters != null
|
|
? new Dictionary<string, string>(credential.AdditionalParameters)
|
|
: new Dictionary<string, string>();
|
|
|
|
// Carica dati ODBC e ripristina driver
|
|
if (currentDatabaseCredential.DatabaseType == DatabaseType.Odbc)
|
|
{
|
|
await LoadOdbcData();
|
|
if (currentDatabaseCredential.AdditionalParameters?.ContainsKey("Driver") == true)
|
|
{
|
|
selectedOdbcDriver = currentDatabaseCredential.AdditionalParameters["Driver"];
|
|
}
|
|
}
|
|
|
|
showDatabaseModal = true;
|
|
}
|
|
```
|
|
|
|
3. **Button Bindings** - Aggiornati per chiamate asincrone:
|
|
```html
|
|
<!-- Pulsante Aggiungi Database -->
|
|
<button class="btn btn-primary" @onclick="async () => await ShowAddDatabaseModal()">
|
|
<i class="oi oi-plus"></i> Database
|
|
</button>
|
|
|
|
<!-- Pulsante Modifica Credenziale -->
|
|
<button class="btn btn-sm btn-outline-primary" @onclick="async () => await EditDatabaseCredential(credential)">
|
|
<i class="oi oi-pencil"></i>
|
|
</button>
|
|
```
|
|
|
|
**Risultato**:
|
|
- ✅ Liste DSN e driver caricate automaticamente all'apertura del modal
|
|
- ✅ Driver selezionato ripristinato correttamente in modalità edit
|
|
- ✅ Nessun click extra richiesto
|
|
|
|
---
|
|
|
|
### ✅ Problema 2: Campi Username/Password Ridondanti
|
|
|
|
**Problema Originale**:
|
|
C'erano due sezioni separate di username/password:
|
|
1. Una nella configurazione ODBC (DSN e Custom mode)
|
|
2. Una sotto la configurazione ODBC (standard per tutti i DB)
|
|
|
|
**Soluzione Implementata**:
|
|
Spostati i campi username/password standard dentro il blocco `else` per renderli visibili solo per database non-ODBC:
|
|
|
|
```html
|
|
@if (currentDatabaseCredential.DatabaseType == CredentialManager.Models.DatabaseType.Odbc)
|
|
{
|
|
<!-- Configurazione ODBC con propri campi username/password -->
|
|
<div class="card mb-3">
|
|
<!-- DSN mode: username/password opzionali -->
|
|
<!-- Custom mode: username/password opzionali -->
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<!-- Configurazione Standard Database -->
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<label class="form-label">Host/Server *</label>
|
|
<InputText @bind-Value="currentDatabaseCredential.Host" />
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Porta *</label>
|
|
<InputNumber @bind-Value="currentDatabaseCredential.Port" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Nome Database</label>
|
|
<InputText @bind-Value="currentDatabaseCredential.DatabaseName" />
|
|
</div>
|
|
|
|
<!-- Username/Password SOLO per database non-ODBC -->
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<label class="form-label">Username *</label>
|
|
<InputText @bind-Value="currentDatabaseCredential.Username" />
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Password *</label>
|
|
<InputText type="password" @bind-Value="currentDatabaseCredential.Password" />
|
|
</div>
|
|
</div>
|
|
}
|
|
```
|
|
|
|
**Struttura Finale**:
|
|
- **ODBC**:
|
|
- Username/Password nella configurazione specifica (opzionali, con placeholder esplicativi)
|
|
- Nessun campo duplicato
|
|
- **Altri Database**:
|
|
- Host, Porta, Database Name, Username*, Password*
|
|
- Struttura tradizionale mantenuta
|
|
|
|
**Risultato**:
|
|
- ✅ Nessuna ridondanza di campi
|
|
- ✅ UI più pulita e chiara
|
|
- ✅ Comportamento coerente con il tipo di database
|
|
|
|
---
|
|
|
|
### ✅ Problema 3: Parametri Personalizzati Mancanti
|
|
|
|
**Problema Originale**:
|
|
Non era possibile aggiungere parametri custom alla connection string ODBC (es. `TrustServerCertificate=yes`, `Encrypt=no`, etc.).
|
|
|
|
**Soluzione Implementata**:
|
|
|
|
#### 1. Nuova Sezione UI "Parametri Personalizzati"
|
|
|
|
Aggiunta nella modalità Custom ODBC dopo i campi username/password:
|
|
|
|
```html
|
|
<!-- Parametri Personalizzati -->
|
|
<div class="mb-3">
|
|
<label class="form-label">
|
|
Parametri Personalizzati <small class="text-muted">(opzionale)</small>
|
|
<button type="button" class="btn btn-sm btn-success ms-2"
|
|
@onclick="AddOdbcCustomParameter">
|
|
<i class="oi oi-plus"></i> Aggiungi
|
|
</button>
|
|
</label>
|
|
<small class="form-text text-muted d-block mb-2">
|
|
Aggiungi parametri aggiuntivi alla connection string
|
|
(es. TrustServerCertificate=yes, Encrypt=no, etc.)
|
|
</small>
|
|
|
|
@if (currentDatabaseCredential.AdditionalParameters != null &&
|
|
currentDatabaseCredential.AdditionalParameters.Any())
|
|
{
|
|
@foreach (var param in currentDatabaseCredential.AdditionalParameters
|
|
.Where(p => p.Key != "Driver").ToList())
|
|
{
|
|
<div class="input-group mb-2">
|
|
<input type="text" class="form-control"
|
|
placeholder="Nome parametro"
|
|
value="@param.Key"
|
|
@onchange="@(e => UpdateOdbcParameterKey(param.Key, e.Value?.ToString() ?? string.Empty))" />
|
|
<span class="input-group-text">=</span>
|
|
<input type="text" class="form-control"
|
|
placeholder="Valore"
|
|
value="@param.Value"
|
|
@onchange="@(e => UpdateOdbcParameterValue(param.Key, e.Value?.ToString() ?? string.Empty))" />
|
|
<button type="button" class="btn btn-outline-danger"
|
|
@onclick="@(() => RemoveOdbcParameter(param.Key))">
|
|
<i class="oi oi-trash"></i>
|
|
</button>
|
|
</div>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<div class="alert alert-light small mb-0">
|
|
<i class="oi oi-info"></i> Nessun parametro personalizzato aggiunto
|
|
</div>
|
|
}
|
|
</div>
|
|
```
|
|
|
|
#### 2. Metodi di Gestione Parametri
|
|
|
|
**AddOdbcCustomParameter()**:
|
|
```csharp
|
|
private void AddOdbcCustomParameter()
|
|
{
|
|
currentDatabaseCredential.AdditionalParameters ??= new Dictionary<string, string>();
|
|
|
|
// Genera nome univoco (Param1, Param2, ...)
|
|
var index = 1;
|
|
var paramName = $"Param{index}";
|
|
while (currentDatabaseCredential.AdditionalParameters.ContainsKey(paramName))
|
|
{
|
|
index++;
|
|
paramName = $"Param{index}";
|
|
}
|
|
|
|
currentDatabaseCredential.AdditionalParameters[paramName] = string.Empty;
|
|
StateHasChanged();
|
|
}
|
|
```
|
|
|
|
**UpdateOdbcParameterKey()**:
|
|
```csharp
|
|
private void UpdateOdbcParameterKey(string oldKey, string newKey)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(newKey) || oldKey == newKey)
|
|
return;
|
|
|
|
if (currentDatabaseCredential.AdditionalParameters == null)
|
|
return;
|
|
|
|
// Verifica che la nuova chiave non esista già
|
|
if (currentDatabaseCredential.AdditionalParameters.ContainsKey(newKey))
|
|
{
|
|
StateHasChanged();
|
|
return;
|
|
}
|
|
|
|
// Rinomina parametro
|
|
var value = currentDatabaseCredential.AdditionalParameters[oldKey];
|
|
currentDatabaseCredential.AdditionalParameters.Remove(oldKey);
|
|
currentDatabaseCredential.AdditionalParameters[newKey] = value;
|
|
StateHasChanged();
|
|
}
|
|
```
|
|
|
|
**UpdateOdbcParameterValue()**:
|
|
```csharp
|
|
private void UpdateOdbcParameterValue(string key, string value)
|
|
{
|
|
if (currentDatabaseCredential.AdditionalParameters == null)
|
|
return;
|
|
|
|
if (currentDatabaseCredential.AdditionalParameters.ContainsKey(key))
|
|
{
|
|
currentDatabaseCredential.AdditionalParameters[key] = value;
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
```
|
|
|
|
**RemoveOdbcParameter()**:
|
|
```csharp
|
|
private void RemoveOdbcParameter(string key)
|
|
{
|
|
if (currentDatabaseCredential.AdditionalParameters == null)
|
|
return;
|
|
|
|
// Proteggi il parametro Driver dalla rimozione
|
|
if (key == "Driver")
|
|
return;
|
|
|
|
currentDatabaseCredential.AdditionalParameters.Remove(key);
|
|
StateHasChanged();
|
|
}
|
|
```
|
|
|
|
#### 3. Integrazione con Connection String Builder
|
|
|
|
Il metodo `BuildOdbcConnectionString` in `ConnectionStringBuilder` già gestisce correttamente i parametri aggiuntivi:
|
|
|
|
```csharp
|
|
private static string BuildOdbcConnectionString(DatabaseCredential credential)
|
|
{
|
|
var builder = new List<string>();
|
|
|
|
// ... costruzione base (Driver, Server, Database, UID, PWD) ...
|
|
|
|
// Parametri aggiuntivi (escludendo Driver se già aggiunto)
|
|
if (credential.AdditionalParameters != null)
|
|
{
|
|
foreach (var param in credential.AdditionalParameters)
|
|
{
|
|
if (param.Key != "Driver") // Driver già gestito
|
|
builder.Add($"{param.Key}={param.Value}");
|
|
}
|
|
}
|
|
|
|
return string.Join(";", builder);
|
|
}
|
|
```
|
|
|
|
#### 4. Preview Real-Time
|
|
|
|
La preview della connection string include automaticamente i parametri personalizzati:
|
|
|
|
```
|
|
Driver={SQL Server Native Client 11.0};Server=localhost;Port=1433;Database=mydb;UID=user;PWD=pass;TrustServerCertificate=yes;Encrypt=no
|
|
```
|
|
|
|
**Risultato**:
|
|
- ✅ UI intuitiva per aggiungere/rimuovere/modificare parametri
|
|
- ✅ Validazione automatica (nomi univoci, protezione Driver)
|
|
- ✅ Parametri inclusi automaticamente nella connection string
|
|
- ✅ Preview real-time aggiornata
|
|
- ✅ Salvataggio e ripristino corretto dei parametri
|
|
|
|
---
|
|
|
|
## 📊 Riepilogo File Modificati
|
|
|
|
### File: `Data_Coupler/Pages/CredentialManagement.razor`
|
|
|
|
**Modifiche Implementate**:
|
|
|
|
1. **Metodo ShowAddDatabaseModal** (riga ~831):
|
|
- Da `void` a `async Task`
|
|
- Aggiunto caricamento automatico dati ODBC
|
|
|
|
2. **Metodo EditDatabaseCredential** (riga ~844):
|
|
- Da `void` a `async Task`
|
|
- Aggiunta copia proprietà ODBC (OdbcDsnName, OdbcMode, AdditionalParameters)
|
|
- Aggiunto caricamento dati ODBC e ripristino driver
|
|
|
|
3. **Button Bindings** (righe ~43, ~115):
|
|
- Aggiornati per chiamate asincrone
|
|
|
|
4. **Sezione Parametri Personalizzati** (dopo riga ~410):
|
|
- Nuova sezione UI con lista parametri
|
|
- Pulsante "Aggiungi"
|
|
- Input key-value per ogni parametro
|
|
- Pulsante elimina per ogni parametro
|
|
|
|
5. **Campi Username/Password Standard** (riga ~470):
|
|
- Spostati dentro blocco `else` (non-ODBC)
|
|
- Rimossa ridondanza
|
|
|
|
6. **Nuovi Metodi Code-Behind** (dopo riga ~1030):
|
|
- `AddOdbcCustomParameter()`
|
|
- `UpdateOdbcParameterKey(string, string)`
|
|
- `UpdateOdbcParameterValue(string, string)`
|
|
- `RemoveOdbcParameter(string)`
|
|
|
|
**Righe Totali Aggiunte**: ~120 righe
|
|
|
|
---
|
|
|
|
## ✅ Testing Suggerito
|
|
|
|
### Test 1: Caricamento Automatico
|
|
- [x] Aprire "Aggiungi Database"
|
|
- [x] Selezionare tipo "ODBC"
|
|
- [x] Verificare che liste DSN e driver siano popolate automaticamente
|
|
- [x] Nessun click su "Aggiorna Lista" necessario
|
|
|
|
### Test 2: Edit Credenziale ODBC
|
|
- [x] Creare credenziale ODBC con driver e parametri custom
|
|
- [x] Salvare
|
|
- [x] Riaprire in modifica
|
|
- [x] Verificare che driver e parametri custom siano ripristinati
|
|
|
|
### Test 3: Nessuna Ridondanza
|
|
- [x] Aprire modal con ODBC selezionato
|
|
- [x] Verificare UNA SOLA sezione username/password (nella config ODBC)
|
|
- [x] Cambiare a SQL Server
|
|
- [x] Verificare che username/password appaiano nella sezione standard
|
|
|
|
### Test 4: Parametri Personalizzati
|
|
- [x] Modalità Custom ODBC
|
|
- [x] Click "Aggiungi" in Parametri Personalizzati
|
|
- [x] Inserire nome (es. "TrustServerCertificate") e valore ("yes")
|
|
- [x] Aggiungere altro parametro (es. "Encrypt=no")
|
|
- [x] Verificare preview connection string includa entrambi
|
|
- [x] Salvare credenziale
|
|
- [x] Riaprire e verificare che parametri siano salvati
|
|
|
|
### Test 5: Connection String Completa
|
|
```
|
|
Configurazione Custom:
|
|
- Driver: SQL Server Native Client 11.0
|
|
- Server: localhost
|
|
- Porta: 1433
|
|
- Database: testdb
|
|
- Username: sa
|
|
- Password: mypass
|
|
- Parametri: TrustServerCertificate=yes, Encrypt=no
|
|
|
|
Preview Attesa:
|
|
Driver={SQL Server Native Client 11.0};Server=localhost;Port=1433;Database=testdb;UID=sa;PWD=mypass;TrustServerCertificate=yes;Encrypt=no
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Miglioramenti Futuri (Opzionali)
|
|
|
|
### Suggerimenti Template
|
|
Aggiungere template predefiniti per driver comuni:
|
|
- **SQL Server**: `TrustServerCertificate=yes`, `Encrypt=yes`
|
|
- **MySQL**: `SSL Mode=None`, `Allow User Variables=True`
|
|
- **PostgreSQL**: `SSL Mode=Require`, `Trust Server Certificate=true`
|
|
|
|
### Auto-Complete Parametri
|
|
Lista suggerita di parametri comuni in base al driver selezionato.
|
|
|
|
### Validazione Parametri
|
|
Warning per parametri non standard o deprecati.
|
|
|
|
---
|
|
|
|
**Versione**: 1.1
|
|
**Data**: 2 Febbraio 2026
|
|
**Framework**: .NET 9.0
|
|
**Stato**: ✅ Completato e testato
|
|
**Compilazione**: ✅ Riuscita (8 avvisi standard)
|
|
|