Esempio reale di TryUpdateModel, ASP .NET MVC 3

Non riesco a capire, come usare TryUpdateModel e salvare l’architettura MVC allo stesso tempo.

Se non sbaglio, il lavoro con i datacontex deve essere nel modello. Quindi, tale codice

var db=new TestEverybody();//it is class, which was generated by EntityFramework var currentTesting=db.Testing.(t => t.id == id).First(); 

deve essere situato nel Modello, non nel Controller, non è vero?

Ma gli esempi usuali di utilizzo di TryUpdateModel sono i seguenti:

  public ActionResult Edit(Testing obj)//Testing collection { var db = new TestEverybody(); var currentTesting=db.Testing.(t => t.id == obj.id).First(); TryUpdateModel(currentTesting); db.SaveChanges(); return RedirectToAction("Index"); } 

In questo modo non rompe l’architettura MVC? Lavoriamo con il database nel controller, non nella class Model speciale.

Quindi, qual è il modo migliore per utilizzare TryUpdateModel in un progetto reale?

Dato che l’OP ha chiesto, ecco un esempio del modello ViewModel o come mi piace chiamarlo: ASP.NET MVC eseguito correttamente.

Quindi, perché utilizzare un modello specifico della vista

  1. Dovresti solo passare le informazioni alla tua vista di cui ha bisogno.
  2. Spesso è necessario aggiungere ulteriori meta-dati di visualizzazione (come gli attributi titolo / descrizione). Questi non appartengono alle tue quadro.
  3. L’uso di TryUpdateModel / UpdateModel è sbagliato. Non usare (spiegherò perché).
  4. È molto raro che i tuoi modelli di visualizzazione corrispondano esattamente alle tue entity framework. Le persone spesso finiscono per aggiungere ulteriori cruft alle loro quadro o (non molto meglio) semplicemente usando ViewBag piuttosto che le proprietà del modello di visualizzazione fortemente tipizzate.
  5. Se si sta utilizzando un ORM è ansible incorrere in problemi con le proprietà caricate Lazy (N + 1). Le tue opinioni non dovrebbero emettere domande.

Inizieremo con una semplice quadro:

 public class Product { public int Id {get;set;} public string Name {get;set;} public string Description {get;set;} public decimal Price {get;set;} } 

Supponiamo che tu abbia un semplice modulo in cui l’utente può aggiornare solo il Name e la Description del prodotto. Ma stai usando (il molto avido) TryUpdateModel.

Quindi uso un numero qualsiasi di strumenti (come Fiddler) per build un POST da solo e inviare quanto segue:

Nome = WhatverIWant e descrizione = UnluckyFool & Prezzo = 0

Bene, il raccoglitore modello ASP.NET MVC esaminerà la raccolta del modulo di input, verificherà che tali proprietà esistono sull’ quadro e le associeranno automaticamente. Quindi quando chiami “TryUpdateModel” sull’ quadro che hai appena recuperato dal tuo database, tutte le proprietà corrispondenti saranno aggiornate (incluso il Prezzo!). Tempo per una nuova opzione.

Visualizza modello specifico

 public class EditProductViewModel { [HiddenInput] public Guid Id {get;set;} [Required] [DisplayName("Product Name")] public string Name {get;set;} [AllowHtml] [DataType(DataType.MultilineText)] public string Description {get;set;} } 

Questo contiene solo le proprietà di cui abbiamo bisogno a nostro avviso. Si noti che abbiamo anche aggiunto alcuni attributi di convalida, attributi di visualizzazione e alcuni attributi specifici di mvc.

Non essendo limitato a ciò che abbiamo nel nostro modello di vista, può rendere le tue opinioni molto più pulite. Ad esempio, possiamo mostrare il nostro intero modulo di modifica avendo il seguente nella nostra vista:

 @Html.EditorFor(model => model) 

Mvc ispezionerà tutti quegli attributi che abbiamo aggiunto al nostro modello di visualizzazione e collegherà automaticamente convalide, etichette e i campi di input corretti (cioè una textarea per la descrizione).

POSTARE il modulo

 [HttpPost] public ActionResult EditProduct(EditProductViewModel model) { var product = repository.GetById(model.Id); if (product == null) { return HttpNotFound(); } // input validation if (ModelState.IsValid) { // map the properties we **actually** want to update product.Name = model.Name; product.Description = model.Description; repository.Save(product); return RedirectToAction("index"); } return View(model) } 

È abbastanza ovvio da questo codice che cosa fa. Non abbiamo alcun effetto indesiderato quando aggiorniamo la nostra quadro dal momento che stiamo impostando esplicitamente le proprietà sulla nostra quadro.

Spero che questo spieghi il modello View-Model abbastanza da permetterti di usarlo.

Quindi, tale codice deve essere situato nel Modello, non nel Controller, non è vero?

Non necessariamente. Personalmente preferisco inserire il codice di accesso ai dati in un repository. Quindi utilizzare l’iniezione del costruttore per passare alcune specifiche implementazioni del repository al controller (ad esempio, se stavo usando EF, scriverei un’implementazione del repository EF). Quindi il controller sarà simile a questo:

 public class HomeController: Controller { private readonly IMyRepository _repository; public HomeController(IMyRepository repository) { _repository = repository; } public ActionResult Edit(int id) { var currentTesting = _repository.GetTesting(id); TryUpdateModel(currentTesting); _repository.SaveChanges(); return RedirectToAction("Index"); } }