La vista non dovrebbe eseguire la convalida?

10

Stavo leggendo " In MVC un modello dovrebbe gestire la convalida? "perché ero curioso di sapere dove la logica di validazione dovrebbe andare in un sito MVC. Una riga nella risposta in alto va così: "i controllori dovrebbero gestire la convalida, i modelli dovrebbero gestire la verifica".

Mi è piaciuto, ma mi ha lasciato il dubbio sul perché non avremmo convalidato i dati nella vista, per diversi motivi:

  1. Le viste hanno generalmente un valido supporto di convalida (librerie JS, tag HTML5)
  2. Le viste possono essere convalidate localmente, riducendo l'IO di rete
  3. L'interfaccia utente è già stata progettata tenendo conto del tipo di dati (calendari per le date, filatori per i numeri), rendendolo un piccolo passo dalla convalida

Convalidare in più di un posto è contrario al concetto di MVC di isolare le responsabilità, quindi "farlo in entrambi" sembra inappropriato. La validazione dei dati sta solo nel controller, l'approccio dominante?

    
posta WannabeCoder 30.09.2015 - 17:51
fonte

5 risposte

9

Non penso che ci sia un singolo posto in cui puoi dire che tutta la validazione dovrebbe andare. Questo perché abbiamo diverse strategie di programmazione in competizione che lavorano insieme in un sito web standard di asp.net mvc.

In primo luogo abbiamo l'idea di separare la logica del dominio in modelli, la logica "azione" in controller e il display in una vista. Questo si basa sull'idea che tutta la logica avrà luogo sul server con il browser che fornisce semplicemente un rendering della vista.

Quindi estendiamo la vista usando il javascript lato client. Al giorno d'oggi è così avanzato che l'idea del "sito web di una pagina" con Jquery / knockout / angolare è una pratica comune.

Questa pratica può essere equivalente alla scrittura di un'intera applicazione lato client che a sua volta implementa un pattern MVC o MVVM. Denigriamo la vista in un oggetto di trasferimento dati e il controllore in un endpoint del servizio. Spostamento di tutte le business e della logica dell'interfaccia utente nel client.

Ciò può offrire un'esperienza utente migliore, ma ti devi fidare di un cliente sostanzialmente inaffidabile. È quindi necessario eseguire la logica di convalida sul server, indipendentemente dal modo in cui il client precorre la convalida delle sue richieste.

Inoltre, abbiamo spesso requisiti di convalida che non possono essere eseguiti dal cliente. per esempio. 'il mio nuovo ID è unico?'

Qualsiasi applicazione creata con l'obiettivo di fornire la migliore esperienza / prestazione richiederà necessariamente prestiti per più paradigmi di programmazione e farà compromessi su di essi per raggiungere il suo obiettivo.

    
risposta data 30.09.2015 - 18:10
fonte
1

Validating in more than one place is contrary to MVC's concept of isolating responsibilities, so "do it in both" seems inappropriate.

Potrebbero esserci più responsabilità di convalida da considerare qui? Come hai detto nel tuo # 3:

UI is already designed with data-type in mind (calendars for dates, spinners for numbers), making it one small step from validation

Quindi forse è:

Visualizza : convalida il tipo di input, il formato, il requisito ... la convalida dell'input dell'utente di base che non ha nulla a che fare con la logica aziendale. Cattura tutte queste cose soffici prima di generare traffico di rete facendo una richiesta al server.

Modello : convalida i problemi aziendali dei dati. È un valore legale in base alle regole aziendali? Sì, è un valore numerico (ci siamo assicurati che nella vista), ma ha senso?

Solo un pensiero.

    
risposta data 30.09.2015 - 18:48
fonte
1

Ho intenzione di ritenere che sia necessaria la convalida per la persistenza.

Non solo Visualizza, ma Model non dovrebbe gestire neanche la validazione. Durante i miei giorni in IT mi sono reso conto che DDD è uno dei modi per garantire che tu stia effettivamente facendo le cose correttamente, ad es. le classi sono effettivamente responsabili di ciò che dovrebbero essere.

Se segui la progettazione basata sul dominio, i tuoi modelli includono la tua logica aziendale, e questo è quanto. Ma non includono la convalida, perché no?

Supponiamo che tu sia già tanto lontano che stai usando Data Mapper invece di Active Record per mantenere il tuo livello dominio. Tuttavia, vuoi che i modelli vengano convalidati, quindi aggiungi la convalida al tuo Modello.

interface Validation
{
    public function validate();
}

class ConcreteModel extends MyModel implements Validation
{
    public function validate() { // the validation logic goes here }
}

La logica di validazione garantisce, puoi inserire correttamente il modello nel tuo database MySQL ... Passano alcuni mesi e tu decidi, vuoi memorizzare i tuoi Modelli anche in database noSQL, database, che richiedono regole di convalida diverse da MySQL .

Ma hai un problema, hai solo 1 metodo di convalida, ma devi convalidare un Model in 2 modi diversi.

I modelli dovrebbero fare ciò che sono responsabili di fare , devono prendersi cura della propria logica di business e farlo bene . La convalida è legata alla persistenza, non alla logica aziendale, quindi la convalida non appartiene a un modello .

Dovresti invece creare Validator s, che richiederà un modello per convalidare il costruttore come parametro, implementare l'interfaccia Validation e usare questi Validator s per convalidare i tuoi oggetti.

interface Validation
{
    public function validate();
}

class MySQLConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model here
    }
}

class RedisConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model with different set of rules here
    }
}

Se in qualsiasi momento in futuro deciderai di voler aggiungere un altro metodo di convalida per un altro livello di persistenza (perché hai deciso che Redis e MySQL non sono più la strada da percorrere), creerai un altro Validator e userai la tua IoC container per ottenere l'istanza corretta in base al config .

    
risposta data 30.09.2015 - 22:22
fonte
1

Per molti sviluppatori, Fat models contro Stupid Ugly Controllers è il metodo preferito.

Il concetto di base nel testo è

... So always remember that the Model is not just the database. Even the data you get from web services can be expressed as a Model! Yes, even Atom feeds! Frameworks which rattle off introductions to the Model, almost never explain this upfront which only exacerbates misunderstandings.

e

The View should only be concerned with generating and presenting a UI so users can communicate intent to the Model. Controllers are the orchestrators who translate UI inputs into actions on the Model and pass back output from whatever View has been made aware of the Model(s) its presenting. Controllers must define application behaviour only in the sense that they map user input onto calls in Models, but beyond that role it should be clear all other application logic is contained within the Model. Controllers are lowly creatures with minimal code who just set the stage and let things work in an organised fashion.

La vista dovrebbe riguardare solo la generazione e la presentazione di un'interfaccia utente in modo che gli utenti possano comunicare l'intento al modello è la parte importante. Un modello dovrebbe definire i dati memorizzati, quindi deve anche essere responsabile della verifica della validità dei dati.

Quando prendi nota di una persona, ogni persona deve avere un numero ID univoco dato dal paese. Questo controllo (generalmente) viene eseguito dal controllo della chiave UNIQUE dal database. Ciascun dato numero ID dovrebbe soddisfare alcuni passaggi di controllo (la somma delle cifre dispari dovrebbe essere uguale alla somma delle cifre pari, ecc.). Questo tipo di controlli dovrebbe essere eseguito da Model

Il controllore sta raccogliendo dati da Model e li ha passati a View , o al contrario, raccoglie i dati utente tramite View e li passa a Model . Qualsiasi restrizione di accesso ai dati e convalida non dovrebbe essere effettuata da Controller . Era il Controller che raccoglie i dati dei cookie ed era il Model che controlla se si tratta di una sessione valida o l'utente ha accesso a questa parte dell'applicazione.

View è l'interfaccia utente che raccoglie i dati dall'utente o presenti all'utente. Semplici controlli possono essere fatti da View come l'input dell'utente indirizzo e-mail o meno (quindi questo può essere fatto anche nella vista) IMO.

View è il lato client, e non dovresti spingere l'input dell'utente. Javascripts potrebbe non funzionare sul lato client, un utente può utilizzare script scritti a mano per modificarli o disabilitare lo script utilizzando il browser. È possibile impostare script di convalida sul lato client, ma mai non dovresti mai spingerli e effettua il controllo reale sul livello Model .

    
risposta data 01.10.2015 - 13:47
fonte
0

Le viste dovrebbero eseguire convalide per scopi ff:

  1. ) Una convalida del front end può ridurre il traffico di dati nel server.
  2. ) gestisce i dati non validi prima che possano viaggiare sul tuo server.
  3. ) se desideri una maggiore sicurezza, una combinazione di front-end e back-end Validazione è migliore.
risposta data 01.10.2015 - 05:38
fonte

Leggi altre domande sui tag