Compartir vía


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.

Screenshot that shows the Movies Controller dot c s tab. Details is selected in the drop down menu on the right.

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 método HTTP Get``Delete no elimina la película especificada, sino que 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. Para más información sobre esto, vea la entrada de blog de Stephen Walther Sugerencia de MVC de ASP.NET n.º 46: no usar eliminar vínculos porque crean vulnerabilidades 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.

Screenshot that shows the M V C Movie Search Index page.

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. Siga me 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