[ASP.NET MVC] ActionResult personalizado para la descargar de documentos

Ya de vuelta al mundo ASP.NET MVC, y antes del parón vacacional, vamos a ver una pequeña aplicación para cargar y descargar documentos de nuestra web.

En primer lugar, implementaremos el método de carga. Nuestra proyecto nos debe permitir cargar documentos dentro del sitio web, de forma que estos puedan ser descargados posteriormente por cualquier usuario. ASP.NET MVC soporta la carga de archivos, pero para ello son necesarios dos componentes:

  • un formulario cuyo atributo enctype tenga el valor "multipart/form-data" y contenga una etiqueta de tipo <input type="file"…>
  • una acción del controlador que reciba la información de la carga y la ejecute.

Para ello tras crear nuestro proyecto de tipo ASP.NET MVC 2 Web Application, que llamaremos ManageFiles:

image image

Añadimos un controlador que llamaremos ManageController, y que se encargará de gestionar tanto la carga como la descarga de los documentos:

image

Dentro de este:

  1. Añadimos la referencia
    1. using System.IO;

        de forma que podamos utilizar operaciones de tipo Entrada/Salida con los documentos.

  2. Creamos un ActionResult llamado Upload, que se encargará de cargar el archivo seleccionado en nuestra carpeta Content, y que tendrá el siguiente código:
  1. public ActionResult Upload(HttpPostedFileBase file)
  2.         {
  3.             var fileName = Path.GetFileName(file.FileName);//obtenemos el nombre del archivo a cargar
  4.             file.SaveAs(Server.MapPath(@"~\Content\" + fileName));//guardamos el archivo en la ruta física que corresponde a la ruta virtual del archivo
  5.             return RedirectToAction("Index");//volvemos a la página principal
  6.         }

* Para cargar un archivo en una ruta específica del servidor es necesario usar la clase HttpPostedFileBase

A continuación, abrimos la vista Index que se crea por defecto y dentro del apartado de contenido principal, añadimos el siguiente código que se encargará de mostrarnos el formulario que nos permite navegar por los archivos de nuestro equipo, y que ejecuta la acción de Upload:

  1. <form action="/Manage/Upload" method="post" enctype="multipart/form-data"/>
  2.     <label>Filename:<input type ="file" name="file"/></label>
  3.     <input type="submit" value="Guardar"/>

Para que podamos acceder de forma sencilla a este área de la aplicación, añadimos una nueva pestaña dentro del menú de la página maestra que se encuentra dentro de la carpeta ViewsShared, mediante el siguiente código:

  1. <li><%: Html.ActionLink("Gestión Documental", "Index", "Manage")%></li>

Si ejecutamos la aplicación y accedemos a la sección Gestión Documental, al pulsar al botón Examinar ya podemos navegar por los documentos de nuestro equipo sin problema, y una vez que pulsamos al botón Guardar podemos ver como el archivo examinado se guarda en la ruta indicada:

image image image

Por otro lado, después de ver el proceso de carga, el cual la mayoría ya habrá implementado de una forma u otra, llegamos a la parte que da título al articulo, el proceso de descarga. Este viene a complementar la carga de archivos con la posibilidad de poder abrir o descargar archivos almacenados en el servidor. Para ello es necesario implementar una clase personalizada que herede de ActionResult, y a la cual llamaremos GetFile

Hacemos clic con el botón derecho sobre nuestro proyecto y seleccionamos Add >Class 

image image

En dicha clase:

  1. Añadimos la referencia
    1. using System.Web.Mvc;

  2. Configuramos nuestra clase para que herede de ActionResult
  3. Inicializamos los parámetros que necesitamos para poder acceder a nuestros archivos, y que son el nombre y la ruta de los mismos:
  1. public string FileName { get; set; }
  2.         public string Path { get; set; }

    4. Y sobrescribimos el método ExecuteResult, que se encargará de implementar la ventana de descarga ( “content-disposition” ) utilizando el siguiente código:

 

  1. public override void ExecuteResult(ControllerContext context)
  2.         {
  3.             context.HttpContext.Response.Buffer = true;
  4.             context.HttpContext.Response.Clear();
  5.             context.HttpContext.Response.AddHeader("content-disposition", "attachment; filename=" + FileName);
  6.             context.HttpContext.Response.WriteFile(context.HttpContext.Server.MapPath(Path));
  7.         }

A continuación vamos al controlador ManagerController, y añadimos el código, que nos permita descargar el archivo Objetivo.docx, que hemos subido anteriormente a nuestra carpeta Content mediante el proceso de carga :

  1. public GetFile DownloadFile()
  2.         {
  3.  
  4.             return new GetFile
  5.             {
  6.                 
  7.                 FileName = "Objetivo.docx",
  8.                 Path = @"~/Content/Objetivo.docx"
  9.  
  10.             };
  11.         }

Por último añadimos, dentro de la vista Index, un Html.ActionLink que ejecute la acción de descarga:

  1. <%: Html.ActionLink("Descarga de documentos", "DownloadFile", "Manage")%>

Al ejecutar la aplicación, y seleccionar la opción Descarga de documentos vemos que aparece la siguiente pantalla:

image 

Esta sería la forma más básica de implementar la descarga, pero vemos que esta opción no es muy flexible ya que tenemos que indicar el nombre de un archivo en concreto a través del código para poder realizar la descargar, cuando lo ideal seria poder seleccionar el archivo dinámicamente. Por ello en el próximo artículo veremos como mejorar esto para que podamos seleccionar el archivo que nosotros queramos y descargarlo, todo ello a través de la interfaz de usuario.

5 comentarios en “[ASP.NET MVC] ActionResult personalizado para la descargar de documentos”

  1. Hola que tal,muy buen post,no se si me puedan contestar una duda,como seria si quisiera mandar un formulario pero con datos como nombre, direccion y esas cosas, y tambien adjuntar un archivo?, todo en el mismo formulario y enviarlo junto

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *