Compartir a través de


Mejorar los métodos Details y Delete (C#)

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 segura, mucho más sencilla de seguir y muestra más características.

Este tutorial le enseñará los conceptos básicos de la creación de una aplicación web ASP.NET MVC mediante Microsoft Visual Web Developer 2010 Express Service Pack 1, que es una versión gratuita de Microsoft Visual Studio. Antes de empezar, asegúrese de que ha instalado los requisitos previos que se enumeran a continuación. Para instalarlos todos, haga clic en el vínculo siguiente: Instalador de plataforma web. Como alternativa, puede instalar individualmente los requisitos previos mediante los vínculos siguientes:

Si usa Visual Studio 2010 en lugar de Visual Web Developer 2010, instale los requisitos previos haciendo clic en el vínculo siguiente: Requisitos previos de Visual Studio 2010.

Un proyecto de Visual Web Developer con código fuente de C# está disponible para acompañar este tema. Descargue la versión de C#. Si prefiere Visual Basic, cambie a la versión de Visual Basic de este tutorial.

En esta parte del tutorial, realizará algunas mejoras en los métodos Details y Delete generados automáticamente. Estos cambios no son necesarios, pero con solo unos fragmentos de código, puede mejorar fácilmente la aplicación.

Mejora de los métodos Details y Delete

Al aplicar scaffolding al controlador Movie, el código generado por ASP.NET MVC ha funcionado bien, pero puede hacer que sea más sólido con solo unos cambios mínimos.

Abra el controlador Movie y modifique el método Details para que devuelva HttpNotFound cuando no se encuentra una película. También debe modificar el método Details para establecer un valor predeterminado para el id. que se le pasa. (Ha realizado cambios similares al método Edit en la parte 6 de este tutorial). Pero debe cambiar el tipo de valor devuelto del método Details de ViewResult a ActionResult, ya que el método HttpNotFound no devuelve un objeto ViewResult. En el ejemplo siguiente se muestra el método Details modificado.

public ActionResult Details(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

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 un valor de película null, esto podría producir un error en la base de datos.

Del mismo modo, cambie los métodos Delete y DeleteConfirmed para especificar un valor predeterminado para el parámetro ID y devolver HttpNotFound cuando no se encuentre una película. A continuación se muestran los métodos Delete actualizados en el controlador Movie.

// GET: /Movies/Delete/5

public ActionResult Delete(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

//
// POST: /Movies/Delete/5

[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    db.Movies.Remove(movie);
    db.SaveChanges();
    return RedirectToAction("Index");
}

Observe que el método Delete no elimina los datos. 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 = 0)

//
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id = 0)

En Common Language Runtime (CLR) es necesario que los métodos sobrecargados tengan una firma de parámetro única (el mismo nombre de método, pero una lista de parámetros diferente). Pero aquí necesita dos métodos Delete, uno para GET y otro para POST, que deben tener la misma firma. (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. Es lo que ha hecho 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 ASP.NET MVC que almacena datos en una base de datos de SQL Server Compact. Puede crear, leer, actualizar, eliminar y buscar películas.

Captura de pantalla que muestra la página Índice de búsqueda en la aplicación de películas de M V C. La página muestra una lista de cuatro películas.

Este tutorial básico le ha permitido empezar a crear controladores, asociarlos a vistas y pasar datos codificados de forma rígida. Después, ha creado y diseñado un modelo de datos. Code First de Entity Framework ha creado una base de datos a partir del modelo de datos sobre la marcha y el sistema de scaffolding de ASP.NET MVC ha generado automáticamente los métodos de acción y las vistas para las operaciones CRUD básicas. Después, ha agregado un formulario de búsqueda que permite a los usuarios buscar en la base de datos. Ha cambiado la base de datos para incluir una nueva columna de datos y, luego, ha actualizado dos páginas para crear y mostrar estos nuevos datos. Ha agregado validación marcando el modelo de datos con atributos del espacio de nombres DataAnnotations. La validación resultante se ejecuta en el cliente y en el servidor.

Si quisiera implementar la aplicación, es útil probarla primero en el servidor IIS 7 local. Puede usar este vínculo del Instalador de plataforma web para habilitar la configuración de IIS para aplicaciones de ASP.NET. Vea los siguientes vínculos de implementación:

Le animamos a pasar a los tutoriales de nivel intermedio Creación de un modelo de datos de Entity Framework para una aplicación ASP.NET MVC y MVC Music Store, a explorar los artículos de ASP.NET en MSDN y consultar los numerosos vídeos y recursos en https://asp.net/mvc para más información sobre ASP.NET MVC. Los foros de ASP.NET MVC son un excelente lugar para formular preguntas.

Disfrútelo.

— Scott Hanselman (http://hanselman.com y@shanselman en Twitter) y Rick Anderson blogs.msdn.com/rickAndy