2011-01-10 18 views
15

Utilizzare questo approccio per visualizzare i modelli in MVC: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspxCome mantenere la convalida?

lascia una domanda senza risposta nella mia mente. Quindi è ora che l'abbia chiarito.

Se utilizzo il mappatore automatico per mappare le proprietà del dominio su un dto, allora apprezzo che il mio livello dominio possa restituire una serie di regole di convalida quando il dto è mappato su un'entità di dominio che viene salvata.

Tuttavia, non vedo un modo di convalidare la convalida del client e aggiungere gli errori allo stato del modello in modo che corrispondano alla proprietà corretta sul modello di visualizzazione.

Acclamazioni

+1

Buon punto. L'ho fatto nel mio ultimo paio di domande per cercare di porvi rimedio. – nick

risposta

11

ho trovato una questione connessa con alcune risposte interessanti:

Mapping Validation Attributes From Domain Entity to DTO

Ho riflettuto su questo, e in un certo senso è analogo alla situazione che abbiamo con server-side e validazione lato client. (Ad esempio, utilizzo di NHibernate Validator e jQuery.validate).

In questi giorni è ben accettato che sia necessario un set completo di convalida sul lato server e l'aggiunta della convalida sul lato client è un'opzione che è possibile scegliere per rendere l'applicazione più user-friendly. In passato era necessario implementare manualmente la convalida sul lato client, ma si accettava la duplicazione del lavoro a causa del vantaggio nell'usabilità.

Direi che quello con cui abbiamo a che fare qui è molto simile. È avere la convalida nel livello del dominio. Non è possibile fare affidamento sulle applicazioni che consumano per aggiungere sempre la convalida.

Hai quindi l'opzione nell'applicazione di aggiungere la convalida sui tuoi modelli DTO/vista. Lo fai perché è più utile gestire gli errori di convalida nella vista piuttosto che lasciarli passare al dominio che potrebbe generare un'eccezione o dare un messaggio di errore meno utile. Il punto è che dal punto di vista del dominio non ci si basa su questo fatto. Sei ancora fiducioso nel tuo sistema perché sai che se i dati non validi vengono superati, il tuo modello lo catturerà.

Al giorno d'oggi il caso client/server non è un problema perché è stato fatto molto lavoro per automatizzarlo, generando il codice lato client dal codice lato server (ad esempio ModelValidatorProvider in ASP.Net MVC). Credo che man mano che sempre più persone utilizzeranno i modelli di visualizzazione/DTO inizieremo a vedere soluzioni simili per la mappatura automatica della convalida del dominio sui DTO (it's already happening with AutoMapper).

Così, in breve, la mia (pragmatico piuttosto che ideale;)) risposta è:

Accettare la violazione dei DRY, per ora, fare la convalida in entrambi i luoghi, e cercare di contribuire ai progetti che mirano a automatizzare in futuro

+0

La risposta è mia, perché evidenzi abbastanza bene gli scambi commerciali e sottolinea che non esiste una soluzione universalmente perfetta. – nick

2

un approccio comune è quello di mettere tutti i vostri convalida nei modelli vista, in genere utilizzando le annotazioni di dati. MVC ti consente di generare automaticamente la validazione lato client (javascript) dalle annotazioni dei dati. Piuttosto ASCIUTTO.

Le azioni del post del controller eseguono il viewmodel e verificano la proprietà IsValid. In questo modo, si stanno convalidando a client e server con lo stesso codice (o dovrebbe, dico attributi nel caso di annotazioni di dati):

[HttpPost] 
public ActionResult ResetPassword(ResetPasswordViewModel viewModel) 
{ 
    if (ModelState.IsValid) 
    { 
    // convert to dto/entity and pass to next layer 
    // redirect to success page 
    return RedirectToAction("ResetPasswordSuccess"); 
    } 
    // display original view which will display error messages 
    return View(); 
} 

solo aggiungere che soltanto con l'adozione azione di controllo nel viewModel come parametro, il raccoglitore modello MVC predefinito convaliderà automaticamente il tuo viewmodel e aggiungerà eventuali errori alla raccolta di errori ModelState che viene utilizzata per visualizzare gli errori nelle viste.

+2

Per me che non è asciutto perché devo convalidare il modello e la VM - o non mi consente di applicare le mie regole di business al modello perché aggiungo solo la validazione alla VM. – nick

+0

Immagino che tu stia sostanzialmente dicendo che hai preso la decisione progettuale che il tuo dominio sarà sempre consumato dalla tua app Web e che gli sviluppatori della tua app web dovrebbero sempre utilizzare i modelli di visualizzazione piuttosto che le entità di dominio per eseguire azioni CRUD? –

+0

: ad esempio, accetti che il modello di dominio sia vulnerabile a dati errati, perché sai che i tuoi sviluppatori non lo utilizzeranno in questo modo? –

5

Preferisco inserire il modello come proprietà sul ViewModel insieme ad altri campi specifici della vista. In questo modo viene convalidato da MVC durante l'associazione e posso convalidarlo sul back-end quando non viene associato tramite MVC. In questo modo la convalida del client viene fornita da MVC e ottengo modelli puliti con oggetto di convalida non direttamente legato a una vista.

public class MyViewModel 
{ 
    public MyModel MyModel {get;set;} 
    public bool IsSomethingAllowed {get;set;} 
} 

public class MyModel 
{ 
    public int Id {get;set;} 
    [Required] 
    public string Name {get;set;} 
} 
+1

questa è una convenzione che la mia squadra ha deciso. Per i progetti su cui lavoriamo, la perdita della convalida di DRY per motivi di modelli con accoppiamento libero non vale la pena: è meno efficiente e più soggetta a errori. – nick

+1

Ci sono problemi con l'utilizzo di entità di dominio. per esempio. (1) Cosa succede se il tipo non è corretto ad es. non un intero valido? Qualsiasi convalida che hai sulla tua entità di dominio non verrà nemmeno colpita, l'associazione del modello fallirà e riceverai un messaggio generico. Con viewmodels, è possibile utilizzare la stringa per tutte le proprietà, assicurandosi che l'associazione modello funzioni e quindi la convalida viewmodel può rilevare se è un numero intero valido e visualizzare un messaggio di errore personalizzato per l'utente. (2) Se si utilizzano i file di risorse per i messaggi di convalida, gli oggetti del dominio dovranno fare riferimento alla dll del file di risorse. Non molto bello! –

+0

Non molto simpatico, sono d'accordo. Ma vuoi applicare le regole aziendali nel livello del modello o meno. Questo sembra essere il principale compromesso. Bene, questo lo fai notare. – nick

Problemi correlati