Examinar los métodos Details y Delete
por Rick Anderson
Nota:
Hay disponible aquí una versión actualizada de este tutorial que usa ASP.NET MVC 5 y Visual Studio 2013. Es más seguro, mucho más sencillo de seguir y muestra más características.
En esta parte del tutorial, examinará los métodos Details
y Delete
generados automáticamente.
Examinar los métodos Details y Delete
Abra el controlador Movie
y examine el método Details
.
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
El motor de scaffolding de MVC que creó este método de acción agrega un comentario en el que se muestra una solicitud HTTP que invoca el método. En este caso se trata de una solicitud GET
con tres segmentos de dirección URL, el controlador Movies
, el método Details
y un valor ID
.
Code First facilita el proceso de búsqueda de datos con el método Find
. Una característica de seguridad importante integrada en el método es que el código comprueba que el método Find
haya encontrado una película antes de intentar hacer nada con ella. Por ejemplo, un hacker podría introducir errores en el sitio cambiando la dirección URL creada por los vínculos de http://localhost:xxxx/Movies/Details/1
a algo parecido a http://localhost:xxxx/Movies/Details/12345
, o algún otro valor que no represente una película real. Si no comprueba si hay una película null, una película null provocaría un error en la base de datos.
Examine los métodos Delete
y DeleteConfirmed
.
// GET: /Movies/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Movie movie = db.Movies.Find(id);
db.Movies.Remove(movie);
db.SaveChanges();
return RedirectToAction("Index");
}
Tenga en cuenta que el HTTP Get``Delete
método no elimina la película especificada, devuelve una vista de la película donde puede enviar (HttpPost
) la eliminación. La acción de efectuar una operación de eliminación en respuesta a una solicitud GET (o con este propósito efectuar una operación de edición, creación o cualquier otra operación que modifique los datos) genera una vulnerabilidad de seguridad.
El método HttpPost
que elimina los datos se denomina DeleteConfirmed
para proporcionar al método HTTP POST una firma o nombre únicos. Las dos firmas de método se muestran a continuación:
// GET: /Movies/Delete/5
public ActionResult Delete(int? id)
//
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
Common Language Runtime (CLR) requiere métodos sobrecargados para disponer de una firma de parámetro única (mismo nombre de método, pero lista de parámetros diferente). En cambio, aquí necesita dos métodos Delete (uno para GET y otro para POST) que tienen la misma firma de parámetro. (ambos deben aceptar un número entero como parámetro).
Para solucionarlo, tiene dos opciones. Una consiste en asignar nombres diferentes a los métodos. que es lo que hizo el mecanismo de scaffolding en el ejemplo anterior. Pero esto implica un pequeño problema: ASP.NET asigna los segmentos de una dirección URL a los métodos de acción por nombre, de modo que si cambia el nombre de un método, el enrutamiento seguramente no podrá encontrar dicho método. La solución es la que ve en el ejemplo, que consiste en agregar el atributo ActionName("Delete")
al método DeleteConfirmed
. De esta forma se realiza la asignación para el sistema de enrutamiento a fin de que una dirección URL que incluya /Delete/ para una solicitud POST busque el método DeleteConfirmed
.
Otra manera de evitar un problema con los métodos que tienen nombres y firmas idénticos consiste en cambiar la firma del método POST artificialmente para incluir un parámetro adicional sin usar. Por ejemplo, algunos desarrolladores agregan un tipo de parámetro FormCollection
que se pasa al método POST y, después, simplemente no usan el parámetro:
public ActionResult Delete(FormCollection fcNotUsed, int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
db.Movies.Remove(movie);
db.SaveChanges();
return RedirectToAction("Index");
}
Resumen
Ahora tiene una aplicación completa MVC de ASP.NET que almacena datos en una base de datos de base de datos local. Puede crear, leer, actualizar, eliminar y buscar películas.
Pasos siguientes
Después de compilar y probar una aplicación web, el siguiente paso es ponerla a disposición de otras personas para que la usen a través de Internet. Para ello, debe implementarla en un proveedor de hospedaje web. Microsoft ofrece hospedaje web gratuito para hasta 10 sitios web en una cuenta de evaluación gratuita de Windows Azure. Le sugiero que siga el siguiente tutorial: Implementar una aplicación segura MVC de ASP.NET con pertenencia, OAuth y SQL Database en un sitio web de Windows Azure. Un excelente tutorial de nivel intermedio de Tom Dykstra: Crear un modelo de datos de Entity Framework para una aplicación MVC de ASP.NET. Stackoverflow y los foros de MVC de ASP.NET son un excelente lugar para formular preguntas. Sígame en Twitter para estar al día de mis tutoriales más recientes.
Le agradecemos sus comentarios.
— Rick Anderson Twitter: @RickAndMSFT
— Scott Hanselman Twitter: @shanselman