ASP.Net MVC non gestisce automaticamente il postback tra le pagine: avremo quindi bisogno di un meccanismo alternativo per recuperare i dati inviati al server dal browser dell'utente.
Una possibile soluzione consiste nell'utilizzare la proprietà Request.Form
, come eravamo abituati a fare in Classic ASP:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(int id, FormCollection values) { GalleryDataContext context = new GalleryDataContext(); GalleryImage image = context.GetImageById(id); // Aggiorna le proprietà dell'immagine image.FileName = Request.Form["FileName"]; image.FileExtension = Request.Form["FileExtension"]; image.Description = Request.Form["Description"]; context.SubmitChanges(); // Reindirizza l'utente all'immagine aggiornata return RedirectToAction("Detail", new { id = image.ImageId }); }
Sebbene questo codice sia perfettamente funzionante, risulta prolisso, poco scalabile e di difficile manutenzione.
ASP.NET MVC fornisce due diversi sistemi per gestire i dati. Il primo utilizza la funzione UpdateModel
per automatizzare l'aggiornamento dei dati:
public ActionResult Edit(int id, FormCollection values) { GalleryDataContext context = new GalleryDataContext(); GalleryImage image = context.GetImageById(id); // Aggiorna le proprietà dell'immagine UpdateModel<GalleryImage>(image); context.SubmitChanges(); // Reindirizza l'utente all'immagine aggiornata return RedirectToAction("Detail", new { id = image.ImageId }); }
UpdateModel è una funzione dichiarata nella classe Controller
che, attraverso l'uso della Reflection, associa il nome di una proprietà del Model a quello di un campo di input presente nella pagina. Così il campo FileName
verrà associato con la proprietà FileName
della classe GalleryImage
, il campo FileExtension
con la proprietà FileExtension
e così via.
L'istruzione UpdateModel<GalleryImage>(image)
ha sostituito interamente la sintassi basata su Request.Form
.
Esistono due versioni di UpdateModel
: la prima, che abbiamo visto nell'esempio, fa uso dei generics e accetta come parametri il tipo del Model (in questo caso GalleryImage
) e l'istanza dell'oggetto da aggiornare con i nuovi dati (nel nostro caso image
).
La seconda versione identifica il tipo del Model tramite Reflection e non fa uso dei generics. Personalmente preferisco utilizzare la prima variante che, oltre ad essere leggermente più performante grazie all'uso dei generics, ci consente di avere completo controllo sul tipo dell'oggetto con cui stiamo lavorando.
Un sistema alternativo alla funzione UpdateModel
consiste nel passare direttamente l'oggetto del Model su cui stiamo lavorando come parametro della nostra azione:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(GalleryImage image) { // Tutto ok, aggiunge la nuova immagine al database GalleryDataContext context = new GalleryDataContext(); context.GalleryImages.InsertOnSubmit(image); context.SubmitChanges(); // Reindirizza l'utente all'immagine appena aggiunta return RedirectToAction("Detail", new { id = image.ImageId }); // Mostra di nuovo la vista return View(); }
Il listato precedente contiene il codice per l'azione che gestisce il POST nel caso di creazione di una nuova immagine. L'azione del controller ha come parametro GalleryImage image
che rappresenta la nuova immagine da inserire nel database. ASP.Net MVC si preoccuperà automaticamente di instanziare un nuovo oggetto di tipo GalleryImage
e di popolarlo con i dati inseriti dall'utente all'interno del form.
Anche in questo caso il risparmio nella quantità di codice da scrivere è evidente: sarà infatti sufficiente aggiungere l'oggetto che ASP.NET ha creato per noi all'interno del database e reindirizzare l'utente alla pagina successiva.