La vista non deve eseguire la convalida?


10

Stavo leggendo " In MVC un modello dovrebbe gestire la convalida? " Perché ero curioso di sapere dove dovrebbe andare la logica di convalida in un sito Web MVC. Una riga nella risposta principale è la seguente: "i controller dovrebbero gestire la convalida, i modelli dovrebbero gestire la verifica".

Mi è piaciuto, ma mi sono lasciato chiedendo perché non avremmo eseguito la convalida dei dati nella vista, per diversi motivi:

  1. Le viste in genere hanno un solido supporto di validazione (librerie JS, tag HTML5)
  2. Le viste possono essere validate localmente, riducendo l'IO della rete
  3. L'interfaccia utente è già progettata tenendo presente il tipo di dati (calendari per le date, spinner per i numeri), rendendolo un piccolo passo dalla convalida

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


Il problema qui potrebbe essere quello della falsa dicotomia: non vi è alcun motivo per cui non è possibile effettuare la convalida in più punti e pensare alla situazione come "o-o-non-entrambi" potrebbe offuscare la tua visione (gioco di parole!) Di questa domanda . Fare una forma di convalida sul lato client in un sito Web, ad esempio, può essere davvero utile perché gli utenti ricevono un feedback immediato, ma non è affidabile, quindi non può essere l'unica convalida.
Miles Rout,

Risposte:


10

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

Innanzitutto abbiamo l'idea di separare la logica del dominio in modelli, la logica dell'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 utilizzando JavaScript lato client. Questo è così avanzato in questi giorni che l'idea del "sito Web a una pagina" con Jquery / knockout / angolare è pratica comune.

Questa pratica può essere equivalente alla scrittura di un'intera applicazione lato client che implementa a sua volta un modello MVC o MVVM. Denigriamo la vista su un oggetto di trasferimento dati e il controller su un endpoint di servizio. Spostamento di tutta la logica aziendale e dell'interfaccia utente nel client.

Questo può offrire un'esperienza utente migliore, ma devi fidarti di un client sostanzialmente inaffidabile. Quindi è ancora necessario eseguire la logica di convalida sul server, indipendentemente da quanto il client pre-convalida le 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 offrire la migliore esperienza / prestazione prenderà necessariamente in prestito diversi paradigmi di programmazione e farà compromessi su di essi per raggiungere il suo obiettivo.


4
+1 e da sottolineare: non fidarti mai dei dati pubblicati dal cliente. Mai.
Machado,

Come ho letto questo: "la convalida non è un concetto isolato: tutte le parti dell'applicazione devono essere convalidate l'una contro l'altra in contesti diversi". Ha senso, anche se più lavoro.
WannabeCoder,

sì, ma anche: "potresti avere due (o più) app, tutte seguendo schemi diversi"
Ewan

" den · i · grate : criticare ingiustamente; denigrare. " Non credo che tu stia usando quella parola correttamente. Buona risposta, comunque.
kdbanman,

no, ecco cosa intendevo
Ewan l'

1

La convalida in più di un posto è contraria al concetto di MVC di isolare le responsabilità, quindi "farlo in entrambi" sembra inappropriato.

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

L'interfaccia utente è già progettata tenendo presente il tipo di dati (calendari per le date, spinner per i numeri), rendendolo un piccolo passo dalla convalida

Quindi forse è:

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

Modello : convalida le preoccupazioni commerciali dei dati. È un valore legale secondo le regole aziendali? Sì, è un valore numerico (lo abbiamo assicurato nella vista), ma ha senso?

Solo un pensiero.


1

Presumo che tu abbia bisogno di una convalida per la persistenza.

Non solo View, ma anche Model non dovrebbe gestire la validazione. Durante i miei giorni in IT ho capito che DDD è uno dei modi per assicurarti che tu stia effettivamente facendo le cose correttamente, cioè. le classi sono effettivamente responsabili di ciò che dovrebbero essere.

Quando segui la progettazione basata su dominio, i tuoi modelli includono la tua logica aziendale, e basta. Ma non includono la convalida, perché no?

Supponiamo che tu stia già utilizzando e Data Mappernon Active Recordper mantenere il tuo livello di 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 convalida garantisce che puoi inserire correttamente il modello nel tuo database MySQL ... Passano alcuni mesi e decidi che vuoi archiviare i tuoi modelli anche in database noSQL, database, che richiedono regole di convalida diverse rispetto a MySQL.

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

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

Dovresti Validatorinvece creare s, che richiederà un modello per convalidare il loro costruttore come parametro, implementare l' Validationinterfaccia e usare questi Validators 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), ne creerai semplicemente un altro Validatore utilizzerai il tuo IoCcontenitore per ottenere l'istanza giusta in base sul tuo config.


1

Per molti sviluppatori, il metodo preferito è rappresentato dai modelli Fat contro Stupid Ugly Controller .

Il concetto di base nel testo è

... Quindi ricorda sempre che il Modello non è solo il database. Anche i dati che ricevi dai servizi web possono essere espressi come modello! Sì, anche i feed Atom! I frame che scuotono le presentazioni del Modello, non spiegano quasi mai questo anticipo che aggrava solo i malintesi.

e

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 . I controller sono gli orchestratori che traducono gli input dell'interfaccia utente in azioni sul modello e restituiscono l'output da qualunque View sia stato reso consapevole del modello o dei modelli che presenta. I controller devono definire il comportamento dell'applicazione solo nel senso che associano l'input dell'utente alle chiamate nei modelli, ma oltre quel ruolo dovrebbe essere chiaro che tutte le altre logiche dell'applicazione sono contenute nel modello. I controller sono creature modeste con un codice minimo che creano le condizioni e lasciano che le cose funzionino in modo organizzato.

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

Quando si registra il record di una persona, ogni persona deve avere un numero ID univoco assegnato dal paese. Questo controllo (generalmente) viene eseguito dal UNIQUEcontrollo chiave da parte del database. Ciascun dato numero ID deve soddisfare alcune fasi di controllo (la somma delle cifre dispari deve essere uguale alla somma delle cifre pari ecc.). Questo tipo di controlli dovrebbe essere eseguito dalModel

Il controller sta raccogliendo dati da Modele li trasferisce a View, o invertire, raccoglie i dati dell'utente Viewe li passa a Model. Qualsiasi restrizione all'accesso ai dati e alla loro convalida non dovrebbe essere effettuata dal Controller. È stato Controllerchi raccoglie i dati sui cookie ed è stato quello Modelche controlla se si tratta di una sessione valida o l'utente ha accesso a questa parte dell'applicazione.

Viewè l'interfaccia utente che raccoglie dati dall'utente o presenta dati all'utente. Semplici controlli possono essere eseguiti Viewdall'utente come l' indirizzo e-mail di input dell'utente o meno (quindi ciò può essere fatto anche nella vista) IMO.

View è il lato client e non dovresti inserire l'input dell'utente. I Javascripts potrebbero non essere eseguiti sul lato client, un utente può utilizzare gli script scritti a mano per modificarli o disabilitare lo script tramite il browser. Puoi impostare gli script di convalida sul lato client, ma mai non dovresti mai spingerli e fare il vero controllo sul Modellivello.


Solo per sottolineare, l'opinione che riguarda solo l'interfaccia utente non significa che non possa fare alcuna forma di convalida: fornire un feedback immediato agli utenti quando commettono un errore è in realtà una parte molto importante del perché lo scripting lato client è utile, nel contesto di MVC applicato ai siti Web.
Miles Rout,

@MilesRout infatti intendo che con Simple checks can be done by the View like the user input e-mail address or not forse non è così chiaro. Ma quello che hai detto è anche vero per me, i controlli semplici e facili possono essere fatti facilmente nella vista.
FallenAngel,

Non ero in disaccordo con te.
Miles Rout,

0

Le viste devono eseguire le convalide per scopi ff:

  1. ) Una convalida del front-end può ridurre il traffico di dati nel tuo server.
  2. ) gestisce dati non validi prima che possano viaggiare nel tuo server.
  3. ) se desideri una maggiore sicurezza, è meglio una combinazione di front-end e back-end.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.