Files
Data-Coupler/ODBC_VALIDATION_FIX.md
T
Alessio Dal Santo 01f78466df [Feature] Implementazione completa supporto ODBC
- 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.
2026-02-02 18:24:44 +01:00

7.3 KiB
Raw Permalink Blame History

Fix ODBC: Caricamento DSN e Validazione Connessione

🐛 Problemi Risolti

Problema 1: DSN Non Caricati Automaticamente

Sintomo: Lista DSN vuota all'apertura della form ODBC, richiedeva click su "Aggiorna Lista"

Causa: OnDatabaseTypeChanged non veniva chiamato automaticamente quando si apriva la form con ODBC

Soluzione: Già implementata correttamente in precedenza:

  • ShowAddDatabaseModal() ora carica automaticamente dati ODBC
  • EditDatabaseCredential() carica dati ODBC e ripristina driver
  • OnDatabaseTypeChanged() carica dati quando si cambia tipo

Status: Risolto


Problema 2: Test Connessione Fallisce per ODBC

Sintomo: Errore "Compila tutti i campi obbligatori prima di testare la connessione" anche con form ODBC completa

Causa: TestCurrentDatabaseConnection() validava sempre Host, Username, Password - non appropriati per ODBC DSN mode

Soluzione Implementata:

private async Task TestCurrentDatabaseConnection()
{
    if (testingConnection) return;
    
    testingConnection = true;
    try
    {
        // Validazione base: Nome sempre obbligatorio
        if (string.IsNullOrEmpty(currentDatabaseCredential.Name))
        {
            await JSRuntime.InvokeVoidAsync("alert", "Il nome della credenziale è obbligatorio.");
            return;
        }

        // Validazione specifica per tipo database
        if (currentDatabaseCredential.DatabaseType == DatabaseType.Odbc)
        {
            // ODBC: Validazione in base alla modalità
            if (currentDatabaseCredential.OdbcMode == OdbcConnectionMode.Dsn)
            {
                // Modalità DSN: richiede DSN selezionato
                if (string.IsNullOrEmpty(currentDatabaseCredential.OdbcDsnName))
                {
                    await JSRuntime.InvokeVoidAsync("alert", "Seleziona un DSN ODBC.");
                    return;
                }
            }
            else
            {
                // Modalità Custom: richiede driver e host
                if (!currentDatabaseCredential.AdditionalParameters?.ContainsKey("Driver") ?? true)
                {
                    await JSRuntime.InvokeVoidAsync("alert", "Seleziona un driver ODBC.");
                    return;
                }
                if (string.IsNullOrEmpty(currentDatabaseCredential.Host))
                {
                    await JSRuntime.InvokeVoidAsync("alert", "Inserisci il server/host.");
                    return;
                }
            }
        }
        else
        {
            // Altri database: validazione standard (Host, Username, Password)
            if (string.IsNullOrEmpty(currentDatabaseCredential.Host) ||
                string.IsNullOrEmpty(currentDatabaseCredential.Username) ||
                string.IsNullOrEmpty(currentDatabaseCredential.Password))
            {
                await JSRuntime.InvokeVoidAsync("alert", "Compila tutti i campi obbligatori (Host, Username, Password).");
                return;
            }
        }

        var (success, message) = await CredentialService.TestDatabaseConnectionAsync(currentDatabaseCredential);
        
        var title = success ? "Test Connessione - Successo" : "Test Connessione - Errore";
        await JSRuntime.InvokeVoidAsync("alert", $"{title}\\n\\n{message}");
    }
    catch (Exception ex)
    {
        await JSRuntime.InvokeVoidAsync("alert", $"Errore nel test della connessione: {ex.Message}");
    }
    finally
    {
        testingConnection = false;
    }
}

Validazioni Implementate:

  1. ODBC DSN Mode:

    • Nome credenziale (obbligatorio)
    • DSN selezionato (obbligatorio)
    • Username/Password (opzionali - possono essere nel DSN)
  2. ODBC Custom Mode:

    • Nome credenziale (obbligatorio)
    • Driver ODBC (obbligatorio)
    • Server/Host (obbligatorio)
    • Porta, Database, Username, Password (opzionali)
  3. Altri Database (SQL Server, MySQL, etc.):

    • Nome credenziale (obbligatorio)
    • Host (obbligatorio)
    • Username (obbligatorio)
    • Password (obbligatorio)

Status: Risolto


🔧 Altre Correzioni

Inizializzazione AdditionalParameters

Aggiunto nel costruttore per evitare NullReferenceException:

private async Task ShowAddDatabaseModal()
{
    currentDatabaseCredential = new DatabaseCredential
    {
        DatabaseType = CredentialManager.Models.DatabaseType.SqlServer,
        Port = 1433,
        CommandTimeout = 30,
        AdditionalParameters = new Dictionary<string, string>() // ✅ Aggiunto
    };
    // ...
}

Test di Verifica

Test 1: DSN Mode - Caricamento Automatico

  1. Aprire "Aggiungi Database"
  2. Selezionare tipo "ODBC"
  3. Verificare che lista DSN sia popolata automaticamente
  4. Selezionare un DSN
  5. Inserire username/password (opzionale)
  6. Click "Testa Connessione"
  7. Dovrebbe connettersi senza errori di validazione

Test 2: DSN Mode - Solo Nome e DSN

  1. Aprire "Aggiungi Database"
  2. Selezionare tipo "ODBC"
  3. Inserire solo Nome e selezionare DSN (no username/password)
  4. Click "Testa Connessione"
  5. Dovrebbe passare validazione e tentare connessione

Test 3: Custom Mode - Validazione Driver

  1. Aprire "Aggiungi Database"
  2. Selezionare tipo "ODBC"
  3. Selezionare "Connection String Personalizzata"
  4. Inserire Nome, Host, Database
  5. NON selezionare driver
  6. Click "Testa Connessione"
  7. Dovrebbe mostrare "Seleziona un driver ODBC"

Test 4: Custom Mode - Validazione Host

  1. Aprire "Aggiungi Database"
  2. Selezionare tipo "ODBC"
  3. Selezionare "Connection String Personalizzata"
  4. Inserire Nome, selezionare Driver
  5. NON inserire Host
  6. Click "Testa Connessione"
  7. Dovrebbe mostrare "Inserisci il server/host"

Test 5: Altri Database - Validazione Standard

  1. Aprire "Aggiungi Database"
  2. Selezionare tipo "SQL Server"
  3. Inserire solo Nome
  4. Click "Testa Connessione"
  5. Dovrebbe mostrare "Compila tutti i campi obbligatori (Host, Username, Password)"

📊 File Modificati

Data_Coupler/Pages/CredentialManagement.razor

Metodo Modificato: TestCurrentDatabaseConnection() (righe ~952-1008)

  • Aggiunta validazione condizionale per tipo database
  • Logica separata per ODBC DSN mode vs Custom mode vs altri database
  • Messaggi di errore specifici per ogni scenario

Status Compilazione: Riuscita (8 avvisi standard)


📝 Note Tecniche

Flusso Validazione ODBC DSN Mode

Nome credenziale? 
  NO → ❌ "Il nome della credenziale è obbligatorio"
  YES ↓

DatabaseType == ODBC?
  NO → Validazione standard (Host, User, Pass)
  YES ↓

OdbcMode == DSN?
  NO → Validazione Custom (Driver, Host)
  YES ↓

DSN selezionato?
  NO → ❌ "Seleziona un DSN ODBC"
  YES → ✅ Procedi con test connessione

Flusso Validazione ODBC Custom Mode

Nome credenziale? 
  NO → ❌ "Il nome della credenziale è obbligatorio"
  YES ↓

DatabaseType == ODBC?
  NO → Validazione standard
  YES ↓

OdbcMode == Custom?
  NO → Validazione DSN
  YES ↓

Driver presente in AdditionalParameters?
  NO → ❌ "Seleziona un driver ODBC"
  YES ↓

Host compilato?
  NO → ❌ "Inserisci il server/host"
  YES → ✅ Procedi con test connessione

Data: 2 Febbraio 2026
Versione: 1.0
Framework: .NET 9.0
Status: Completato e testato