2010-01-17 3 views
13

Selezionando MVC per lo sviluppo del nostro nuovo sito, mi trovo nel mezzo delle "migliori pratiche" sviluppate intorno a me in tempo reale apparente. Due settimane fa, NerdDinner è stata la mia guida, ma con lo sviluppo di MVC 2, anche se sembra obsoleto. È un'esperienza elettrizzante e mi sento privilegiata a stare in stretto contatto quotidianamente con i programmatori intelligenti.Best practice riguardanti il ​​modello di visualizzazione e gli aggiornamenti del modello con un sottoinsieme di campi

In questo momento sono incappato in un problema su cui non riesco a ottenere una risposta diretta - da tutti i blog comunque - e mi piacerebbe avere una visione della comunità. Si tratta di modifica (leggi: Modifica azione). La maggior parte del materiale, tutorial e blog, si occupa della creazione e visualizzazione del modello. Quindi, anche se questa domanda potrebbe non enunciare una domanda, spero di portare avanti qualche discussione, contribuendo alla mia decisione sul percorso di sviluppo che devo intraprendere.

Il mio modello rappresenta un utente con diversi campi come nome, indirizzo ed e-mail. Tutti i nomi, infatti, sul campo ciascuno per nome, cognome e secondo nome. La vista Dettagli visualizza tutti questi campi ma è possibile modificare solo un set di campi alla volta, ad esempio i tuoi nomi. L'utente espande un modulo mentre gli altri campi sono ancora visibili sopra e sotto. Quindi il modulo che viene pubblicato di nuovo contiene un sottoinsieme dei campi che rappresentano il modello.

Mentre questo è interessante per noi e il nostro problema di layout, per vari motivi, è da evitarlo da parte degli sviluppatori di MVC. Ho letto alcuni schemi e best practice e sembra che questo non sia in linea con il paradigma viewmodel == view. O mi sono sbagliato?

In ogni caso, NerdDinner detta usando FormCollection och UpdateModel. Tutti i campi nulli sono felicemente ignorati. Da allora, la comunità MVC ha abbandonato questo approccio a tal punto che non è stato rilevato un bug in MVC 2. UpdateModel non funziona senza un modello completo nella raccolta dei moduli.

Il view model pattern riceve più lode sembra essere Dedicato modello di vista che contiene una vista del modello personalizzato entità ed è l'unico che il mio problema di progettazione potrebbe essere reso compatibile con. Esso comporta una quantità noiosa di mappatura, anche se alleggerito dall'uso di AutoMapper e dallo ideas di Jimmy Bogard, che può o non può essere utile. Propone anche una relazione 1: 1 tra vista e modello di vista.

In linea con questi paradigmi di progettazione, devo creare una vista e una vista associata per ciascuno dei miei insiemi di campi in espansione. I modelli di visualizzazione sarebbero quasi identici, differendo solo nei campi che sono di sola lettura, le viste contenenti anche marcature molto ripetute. Questo mi sembra assurdo. In futuro potrei voler visualizzare contemporaneamente due, più o tutti i gruppi di campi aperti.

Leggerò con molta attenzione la discussione che spero di suscitare. Molte grazie in anticipo.

+0

"La visualizzazione Dettagli visualizza tutti questi campi ma è possibile modificare solo un set di campi alla volta, ad esempio i propri nomi. "Perché? Questo è più amichevole di lasciare che un utente regoli l'intero modulo in una volta?" – jfar

+1

Hai ragione, lo riformulerò. È solo meno disordinato e più compatto. Puoi avere più indirizzi, aggiungere, eliminare ma siamo ancora lo voglio su una pagina – Martin

+0

Hai spiegato molto bene la tua preoccupazione, ho riscontrato lo stesso problema e mi sono mosso verso il modello 1: 1: ViewModel descritto da Jimmy Bogard. Il problema principale che sto ancora affrontando è mappatura di ViewModels che contengono più modelli di dominio. – WDuffy

risposta

0

Ho lo stesso identico problema, ma non sarei in grado di formularlo così bene.

Nel mio caso, ci sarebbero tonnellate di ViewModels, perché diversi utenti vedrebbero forme diverse basate su un insieme di ruoli. Penso che la relazione 1: 1 tra ViewModel e View sia molto vaga. Cosa succede se scrivo un uber-View che utilizza semplicemente lo EditorForModel e non molto altro? Ora ho una visione, anche se altamente degenerata, di tutto, quindi ho anche un solo ViewModel?

La mia idea era di scrivere un EditorForModel che funzioni non solo in base alla riflessione (ovvero informazioni note al momento della compilazione), ma anche sulle regole di runtime (specifiche del dominio), ad esempio governate dal ruolo dell'utente corrente, l'attuale tempo, ecc.Di conseguenza, è anche necessario scrivere una custom ModelBinder con convalida e una mappatura personalizzata da Model a ViewModel. Tuttavia, questo mi impedisce di scrivere codice stupido e quindi soggetto a errori.

Poiché il mio modello (o DomainModel) contiene molta logica, non desidero che venga modificato tramite ModelBinding. Inoltre, dato che è impossibile sapere quali campi saranno presenti al momento della compilazione, fornire un ViewModel appropriato è impossibile. Tuttavia, è noto il ViewModel massimale "pieno", cioè. La mappatura da ViewModel al modello comporta di nuovo codice personalizzato, ma finché le regole possono essere formalizzate, ciò dovrebbe funzionare.

Scusa il mio testo è molto confuso, ma sono molto confuso in questo momento io stesso, in più devo correre. Come C.T., non ho potuto commentare neanche.

+0

utilizza ValueInjecter http://valueinjecter.codeplex.com/ e associa FormCollection (o Request) alle entità (viene eseguita automaticamente), c'è un'applicazione di esempio asp.net mvc in il download che dimostra questo – Omu

2

Ci sono stati alcuni post di recente sul problema della convalida dei tuoi modelli, risultando in questo post di Brad Wilson "Input Validation vs. Model Validation in ASP.NET MVC".

Il problema iniziale riguardava il modo in cui ASP.NET MVC gestiva la convalida di un modello pubblicato e se c'erano elementi del modello che non si desideravano modificare e non fornivano campi nella vista, ma il proprio i controller funzionavano con l'intero modello, è possibile che qualcuno possa creare un POST sul controller con i campi aggiuntivi.

Pertanto, l'utilizzo di un modello specifico di visualizzazione consente di verificare che solo i campi che si desidera modificare possano essere modificati.

0

Controllare questo. Questo è il modo di andare con ASP.NET MVC 2.

 public void Update(MyModel model) 
     { 
      var myModelObject = MyRepository.GetInstance(model.Id); 
      if(myModelObject != null) 
      { 
       ModelCopier.CopyModel(model, myModelObject); 
      } 
      MyRepository.Save(myModelObject); 
     } 

ModelCopier.CopyModel (obj da, obj a) è una nuova funzione nella sua ultima MvcFutures. Anche essere sicuri di controllare le Extensible modello Binder in MVC Futures 2.

+0

Lo farò, grazie – Martin

+0

Questo non sta davvero usando un modello di vista, anche se è? Sembra solo essere una copia transitoria dell'entità attuale? – UpTheCreek

3

sto facendo in questo modo (la mappatura viene eseguita automaticamente all'interno ModelBuilder con la ValueInjecter):

Ho un asp campione .net-MVC applicazione dove dimostrare le migliori pratiche di fare questo in MVC, si può vedere nel download of the valueinjecter

public ActionResult Edit(long id) 
{ 
     return View(modelBuilder.BuildModel(personService.Get(id))); 
} 

[HttpPost] 
public ActionResult Edit(PersonViewModel model) 
{ 
    if (!ModelState.IsValid) 
     return View(modelBuilder.RebuildModel(model));  
     personService.Save(modelBuilder.BuildEntity(model)); 
     return RedirectToAction("Index"); 
} 

un rapido demo del ValueInjecter:

//build viewmodel 
    personViewModel.InjectFrom(person) 
        .InjectFrom<CountryToLookup>(person); 

//build entity 
    person.InjectFrom(personViewModel) 
      .InjectFrom<LookupToCountry>(personViewModel); 
+0

Cosa sono i principali differenes di Bogards AutoMapper diresti? – Martin

+0

@Martin con l'Automapper devi creare mappature per ogni possibile coppia di oggetti per la mappatura degli oggetti e mostrare come mappare ogni proprietà in parte (se non hanno gli stessi nomi), e devi impostare ignora se non lo fai Ne ho bisogno, ora con ValueInjecter non devi fare tutto questo, anche con ValueInjecter puoi fare lo spianatura e l'unfattening (da un tipo a un altro usando un tuo algoritmo per impostare il valore) ci sono molti esempi in il download – Omu

Problemi correlati