Gestione di un errore di convalida

3

Ho un'app che accetta due parametri: pagamento ricevuto e costo. Quindi calcola le denominazioni di modifica.

È un'app MVP, che chiama un servizio Web WCF, che accede a una DLL del livello del dominio.

Supponiamo che un utente inserisca £ 1 per il pagamento ricevuto e £ 2 per il costo. Chiaramente questo è sbagliato (non ci sono abbastanza soldi). Ho due domande:

  1. Dove l'applicazione deve gestire questa logica di convalida. Nel presentatore? Nel livello di dominio?
  2. L'applicazione dovrebbe generare un'eccezione o restituire un messaggio?

Supponiamo che l'utente inserisca lo stesso valore per il pagamento ricevuto e il costo (le stesse due domande sopra riportate).

Questo articolo, Convalida con un livello di servizio (C #) , parla della convalida nel livello di servizio. Mi piace questa idea poiché significa che tutti i client (MVP, MVC, Mobile, WPF ecc.) Possono utilizzare la convalida.

Tuttavia, questo rende il modello di dominio anemico piuttosto che ricco?

    
posta w0051977 15.06.2017 - 19:34
fonte

3 risposte

2

Supponendo che, nonostante il ragionevole dubbio avanzato nella risposta di VoiceOfUnreason, la regola aziendale sia stata decisa, come la tua domanda presuppone.

Quindi la semplice risposta è che nessun sistema dovrebbe fidarsi del suo input , specialmente (ma non esclusivamente) quando l'input proviene da un utente umano.

Quindi convalidare su ogni livello.

Se si persistono i dati, è necessario implementare questo controllo nel modello dati e gestire le eccezioni nel proprio DAL (livello di accesso ai dati). Da lì, puoi generare eccezioni per essere catturate dal tuo BLL (livello logico aziendale) che utilizza quel DAL.

Il tuo livello dominio dovrebbe implementare anche la regola aziendale nel suo modello. A volte il dominio viene generato almeno in parte dal modello di dati, quindi finirà automaticamente lì. Di nuovo, puoi lanciare un'eccezione se la regola è violata.

Anche il servizio WCF può generare un'eccezione. Questo è ampiamente considerato una buona cosa, purché tu descriva le possibili eccezioni che il tuo servizio potrebbe comportare nel tuo contratto di servizio.

Ora hai protetto il tuo back-end dai dati corrotti, ma vorrebbe dire che devi chiamare il tuo servizio WCF dopo l'input dell'utente, solo per scoprire che c'è un errore. È prassi comune convalidare l'input dell'utente sul front-end senza prima chiamare i servizi back-end, se tale convalida può essere effettuata in base all'input dell'utente stesso (il controllo per un nome utente esistente non può essere fatto come quello, ovviamente, ma verificare se una data di inizio si trova prima di una data di fine è comune).

Questo puoi facilmente fare nel modello della tua applicazione, usando, ad esempio, annotazioni di dati e validazione. In questo caso, fornisci i messaggi di convalida che devono essere inviati all'utente finale.

Prima di inviare i dati utente al servizio WCF, convalidi i dati e, se c'è un errore di convalida, lo comunichi all'utente.

    
risposta data 15.06.2017 - 20:46
fonte
1

Say a user enters £1 for the payment received and £2 for the cost. Clearly this is wrong (there is not enough money).

Ci sono davvero due diverse risposte a questo.

Dal punto di vista del modello di dominio, è necessario valutare se si tratta di un evento aziendale reale da tracciare, solo un errore di immissione dati o un errore di immissione dati che si desidera tracciare. Non c'è nulla di fondamentalmente impossibile nel pagare meno del costo (gestore che compila qualcuno? Tagliando?), Quindi il modello di dominio dovrebbe scegliere la propria politica per gestire questo caso.

Detto questo ... se gli errori di immissione dei dati sono molto più probabili che accettare meno del costo come pagamento, allora una risposta ragionevole è usare un approccio UI basato su attività; vale a dire che presenti un'interfaccia utente che richiede che l'operatore introduca un pagamento sufficiente a coprire il costo OPPURE che l'operatore passi a un'interfaccia utente diversa che è più indulgente (pensa al gestore che ha un override).

    
risposta data 15.06.2017 - 19:59
fonte
1

Tendo ad essere d'accordo con i piloni in generale (non fidarti mai dei tuoi input), ma ci sono alcuni avvertimenti importanti da menzionare. Perché se ingenui controlli in ogni funzione di ogni livello, questo avrà un impatto sulle prestazioni.

Seguo una regola generale che riassumo come "Controlla tutto ciò che è necessario controllare il più vicino possibile alla fonte dell'input."

E questo significa cose diverse per casi diversi:

  • la possibilità di valori dipende dalla natura dei dati (ad esempio, i costi non possono essere negativi, i conteggi devono essere numeri interi, ...). Quindi, questo dovrebbe essere controllato il più vicino possibile all'ingresso, preferibilmente non consentendo all'utente di immettere valori negativi nell'interfaccia utente. Quindi questo controllo è nel livello esterno.

  • la fattibilità dei valori dipende dal caso d'uso effettivo. Posso immaginare che la stessa UI sia usata in un caso in cui le regole aziendali dicono che il costo non può essere più alto del pagamento ricevuto e in un altro caso in cui ciò può effettivamente accadere. Quindi quei controlli che avrei inserito nel servizio WCF utilizzato in quel caso d'uso specifico. La tua interfaccia utente può essere riutilizzata e la DLL non ha bisogno di essere chiamata quando i dati non sono conformi.

  • l'usabilità dei valori dipende dall'algoritmo sottostante. Anche con le regole sopra puoi avere un costo di 0 e un pagamento di 0. Ma se vuoi fare un calcolo in cui usi una trasformazione logaritmica, questo causerà un problema -Infinity. Quindi il metodo effettivo non può trattare valori che sono 0 o più piccoli, e quindi quel metodo dovrebbe controllare il suo input prima che inizi a fare i calcoli.

Sono consapevole che questo non può essere scolpito nella pietra e rimarrà qualche ambiguità, ma a mio modesto parere è il miglior approccio generale al controllo della validazione.

Per quanto riguarda i rapporti: offri sempre ai tuoi utenti un messaggio comprensibile e esplicativo su cosa è andato storto e perché è andato storto. Anche nel secondo e nel terzo caso, rilevare le eccezioni e tradurle in informazioni utili per l'utente finale dovrebbe essere una seconda natura per ogni programmatore. Ancora a mio modesto parere.

    
risposta data 16.06.2017 - 12:29
fonte

Leggi altre domande sui tag