Trabajar con archivos en un sitio de ASP.NET Web Pages (Razor)

por Tom FitzMacken

En este artículo se explica cómo leer, escribir, anexar, eliminar y cargar archivos en un sitio de ASP.NET Web Pages (Razor).

Nota:

Si desea cargar imágenes y manipularlas (por ejemplo, voltearlas o cambiarlas de tamaño), vea Trabajar con imágenes en un sitio de páginas web de ASP.NET.

Lo que aprenderá:

  • Cómo crear un archivo de texto y escribir datos en él.
  • Cómo anexar datos a un archivo existente.
  • Cómo leer un archivo y mostrarlo desde él.
  • Cómo eliminar archivos de un sitio web.
  • Cómo permitir que los usuarios carguen un archivo o varios archivos.

Estas son las ASP.NET características de programación introducidas en el artículo:

  • Objeto File , que proporciona una manera de administrar archivos.
  • El asistente FileUpload.
  • Objeto Path , que proporciona métodos que permiten manipular nombres de archivo y ruta de acceso.

Versiones de software usadas en el tutorial

  • páginas web de ASP.NET (Razor) 2
  • WebMatrix 2

Este tutorial también funciona con WebMatrix 3.

Crear un archivo de texto y escribir datos en él

Además de usar una base de datos en su sitio web, puede trabajar con archivos. Por ejemplo, puede usar archivos de texto como una manera sencilla de almacenar datos para el sitio. (Un archivo de texto que se usa para almacenar datos a veces se denomina archivo plano). Los archivos de texto pueden tener diferentes formatos, como .txt, .xmlo .csv (valores delimitados por comas).

Si desea almacenar datos en un archivo de texto, puede usar el File.WriteAllText método para especificar el archivo que se va a crear y los datos que se van a escribir en él. En este procedimiento, creará una página que contiene un formulario simple con tres input elementos (nombre, apellidos y dirección de correo electrónico) y un botón Enviar . Cuando el usuario envíe el formulario, almacenará la entrada del usuario en un archivo de texto.

  1. Cree una carpeta denominada App_Data, si aún no existe.

  2. En la raíz de su sitio web, cree un archivo denominado UserData.cshtml.

  3. Reemplace el contenido existente por lo siguiente:

    @{
        var result = "";
        if (IsPost)
        {
            var firstName = Request["FirstName"];
            var lastName = Request["LastName"];
            var email = Request["Email"];
    
            var userData = firstName + "," + lastName +
                "," + email + Environment.NewLine;
    
            var dataFile = Server.MapPath("~/App_Data/data.txt");
            File.WriteAllText(@dataFile, userData);
            result = "Information saved.";
        }
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>Write Data to a File</title>
    </head>
    <body>
        <form id="form1" method="post">
        <div>
            <table>
                <tr>
                    <td>First Name:</td>
                    <td><input id="FirstName" name="FirstName" type="text" /></td>
    
                </tr>
                <tr>
                    <td>Last Name:</td>
                    <td><input id="LastName" name="LastName" type="text" /></td>
                </tr>
                <tr>
                    <td>Email:</td>
                    <td><input id="Email" name="Email" type="text" /></td>
                </tr>
                <tr>
                    <td></td>
                    <td><input type="submit" value="Submit"/></td>
                </tr>
            </table>
        </div>
        <div>
        @if(result != ""){
            <p>Result: @result</p>
        }
        </div>
        </form>
    </body>
    </html>
    

    El marcado HTML crea el formulario con los tres cuadros de texto. En el código, se usa la IsPost propiedad para determinar si la página se ha enviado antes de empezar a procesarla.

    La primera tarea consiste en obtener la entrada del usuario y asignarla a variables. A continuación, el código concatena los valores de las variables independientes en una cadena delimitada por comas, que luego se almacena en una variable diferente. Observe que el separador de comas es una cadena contenida entre comillas (","), porque literalmente va a insertar una coma en la cadena grande que está creando. Al final de los datos que concatene, agregue Environment.NewLine. Esto agrega un salto de línea (un carácter de nueva línea). Lo que va a crear con toda esta concatenación es una cadena similar a la siguiente:

    David,Jones,davidj@contoso.com
    

    (Con un salto de línea invisible al final).

    A continuación, cree una variable (dataFile) que contenga la ubicación y el nombre del archivo en el que almacenar los datos. La configuración de la ubicación requiere un control especial. En los sitios web, es una práctica incorrecta hacer referencia en el código a rutas de acceso absolutas, como C:\Folder\File.txt para archivos en el servidor web. Si se mueve un sitio web, una ruta absoluta será incorrecto. Además, para un sitio hospedado (en lugar de en tu propio equipo), usualmente no sabes cuál es la ruta correcta al escribir el código.

    Pero a veces (como ahora, para escribir un archivo), necesita una ruta de acceso completa. La solución consiste en usar el MapPath método del Server objeto . Esto devuelve la ruta de acceso completa a su sitio web. Para obtener la ruta de acceso de la raíz del sitio web, use el operador ~ (para representar la raíz virtual del sitio) en MapPath. (También puede pasarle un nombre de subcarpeta, como ~/App_Data/, para obtener la ruta de acceso de esa subcarpeta). A continuación, puede concatenar información adicional sobre cualquier valor devuelto por el método para crear una ruta de acceso completa. En este ejemplo, agregará un nombre de archivo. (Puede obtener más información sobre cómo trabajar con rutas de acceso de archivos y carpetas en Introducción a ASP.NET programación de páginas web mediante la sintaxis de Razor).

    El archivo se guarda en la carpeta App_Data . Esta carpeta es una carpeta especial en ASP.NET que se usa para almacenar archivos de datos, como se describe en Introducción al trabajo con una base de datos en ASP.NET sitios de páginas web.

    El WriteAllText método del File objeto escribe los datos en el archivo. Este método toma dos parámetros: el nombre (con ruta de acceso) del archivo en el que se va a escribir y los datos reales que se van a escribir. Observe que el nombre del primer parámetro tiene un @ carácter como prefijo. Esto le indica a ASP.NET que estás proporcionando un literal de cadena y que los caracteres como "/" no deben interpretarse de maneras especiales. (Para obtener más información, vea Introducción a ASP.NET programación web mediante la sintaxis de Razor).

    Nota:

    Para que el código guarde archivos en la carpeta App_Data , la aplicación necesita permisos de lectura y escritura para esa carpeta. En el equipo de desarrollo, esto no suele presentar un problema. Sin embargo, al publicar el sitio en el servidor web de un proveedor de hospedaje, es posible que tenga que establecer explícitamente esos permisos. Si ejecuta este código en el servidor de un proveedor de hospedaje y recibe errores, consulte con el proveedor de hospedaje para averiguar cómo establecer esos permisos.

  • Ejecute la página en un explorador.

    Captura de pantalla de la ventana del explorador en la que se muestran los campos Nombre, Apellidos y Texto de correo electrónico con un botón Enviar que los sigue.

  • Escriba los valores en los campos y, a continuación, haga clic en Enviar.

  • Cierre el explorador.

  • Regrese al proyecto y refresque la vista.

  • Abra el archivo data.txt . Los datos que envió en el formulario están en el archivo.

    Captura de pantalla del archivo de datos .txt que muestra que los datos introducidos en los campos del explorador web han sido registrados en el archivo .txt.

  • Cierre el archivo data.txt .

Anexar datos a un archivo existente

En el ejemplo anterior, usó WriteAllText para crear un archivo de texto que tiene solo un fragmento de datos en él. Si llama al método de nuevo y le pasa el mismo nombre de archivo, el archivo existente se sobrescribe completamente. Sin embargo, después de crear un archivo, a menudo desea agregar nuevos datos al final del archivo. Puede hacerlo mediante el AppendAllText método del File objeto .

  1. En el sitio web, realice una copia del archivo UserData.cshtml y asigne el nombre UserDataMultiple.cshtml.

  2. Reemplace el bloque de código antes de la etiqueta de apertura <!DOCTYPE html> por el siguiente bloque de código:

    @{
        var result = "";
        if (IsPost)
        {
            var firstName = Request["FirstName"];
            var lastName = Request["LastName"];
            var email = Request["Email"];
    
            var userData = firstName + "," + lastName +
                "," + email + Environment.NewLine;
    
            var dataFile = Server.MapPath("~/App_Data/data.txt");
            File.AppendAllText (@dataFile, userData);
            result = "Information saved.";
        }
    }
    

    Este código tiene un cambio en él del ejemplo anterior. En lugar de usar WriteAllText, usa el the AppendAllText método . Los métodos son similares, excepto que AppendAllText agrega los datos al final del archivo. Al igual que con WriteAllText, AppendAllText crea el archivo si aún no existe.

  3. Ejecute la página en un explorador.

  4. Escriba los valores de los campos y, a continuación, haga clic en Enviar.

  5. Agregue más datos y vuelva a enviar el formulario.

  6. Vuelva al proyecto, haga clic con el botón derecho en la carpeta del proyecto y, a continuación, haga clic en Actualizar.

  7. Abra el archivo data.txt . Ahora contiene los nuevos datos que acaba de escribir.

    Captura de pantalla del archivo de texto que muestra que los datos introducidos en los campos del explorador web se han registrado sin sobrescribir los datos anteriores.

Leer y mostrar datos de un archivo

Incluso si no necesita escribir datos en un archivo de texto, es probable que a veces necesite leer datos de uno. Para ello, puede volver a usar el File objeto . Puede usar el File objeto para leer cada línea individualmente (separada por saltos de línea) o para leer un elemento individual independientemente de cómo estén separados.

Este procedimiento muestra cómo leer y mostrar los datos que creó en el ejemplo anterior.

  1. En la raíz de su sitio web, cree un archivo denominado DisplayData.cshtml.

  2. Reemplace el contenido existente por lo siguiente:

    @{
        var result = "";
        Array userData = null;
        char[] delimiterChar = {','};
    
        var dataFile = Server.MapPath("~/App_Data/data.txt");
    
        if (File.Exists(dataFile)) {
            userData = File.ReadAllLines(dataFile);
            if (userData == null) {
                // Empty file.
                result = "The file is empty.";
            }
        }
        else {
            // File does not exist.
            result = "The file does not exist.";
        }
    }
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Reading Data from a File</title>
    </head>
    <body>
        <div>
            <h1>Reading Data from a File</h1>
            @result
            @if (result == "") {
                <ol>
                @foreach (string dataLine in userData) {
                <li>
                    User
                    <ul>
                    @foreach (string dataItem in dataLine.Split(delimiterChar)) {
                        <li>@dataItem</li >
                    }
                    </ul>
                </li>
                }
                </ol>
            }
        </div>
    </body>
    </html>
    

    El código comienza leyendo el archivo que creó en el ejemplo anterior en una variable denominada userData, con esta llamada al método :

    File.ReadAllLines(dataFile)
    

    El código para hacerlo está dentro de una if instrucción . Cuando quiera leer un archivo, es recomendable usar el File.Exists método para determinar primero si el archivo está disponible. El código también comprueba si el archivo está vacío.

    El cuerpo de la página contiene dos foreach bucles, uno anidado dentro del otro. El bucle externo foreach obtiene una línea a la vez del archivo de datos. En este caso, las líneas se definen mediante saltos de línea en el archivo, es decir, cada elemento de datos está en su propia línea. El bucle externo crea un nuevo elemento (<li> elemento) dentro de una lista ordenada (<ol> elemento).

    El bucle interno divide cada línea de datos en elementos (campos) mediante una coma como delimitador. (En función del ejemplo anterior, esto significa que cada línea contiene tres campos: el nombre, el apellido y la dirección de correo electrónico, cada uno separado por una coma). El bucle interno también crea una <ul> lista y muestra un elemento de lista para cada campo de la línea de datos.

    El código muestra cómo usar dos tipos de datos, una matriz y el tipo de char datos. La matriz es necesaria porque el File.ReadAllLines método devuelve datos como una matriz. El char tipo de datos es necesario porque el Split método devuelve un array en el que cada elemento es del tipo char. (Para obtener información sobre las matrices, vea Introducción a ASP.NET programación web mediante la sintaxis de Razor).

  3. Ejecute la página en un explorador. Se muestran los datos especificados para los ejemplos anteriores.

    Captura de pantalla de la ventana del navegador que muestra los datos del archivo data dot txt en una matriz.

Sugerencia

Mostrar datos de un archivo delimitado por comas de Microsoft Excel

Puede usar Microsoft Excel para guardar los datos contenidos en una hoja de cálculo como un archivo delimitado por comas (.csv archivo). Cuando lo hace, el archivo se guarda en texto sin formato, no en formato de Excel. Cada fila de la hoja de cálculo está separada por un salto de línea en el archivo de texto y cada elemento de datos está separado por una coma. Puede usar el código que se muestra en el ejemplo anterior para leer un archivo delimitado por comas de Excel simplemente cambiando el nombre del archivo de datos en el código.

Eliminar archivos

Para eliminar archivos de su sitio web, puede usar el File.Delete método . Este procedimiento muestra cómo permitir que los usuarios eliminen una imagen (.jpg archivo) de una carpeta images si conocen el nombre del archivo.

Nota:

Importante En un sitio web de producción, normalmente restringe quién puede realizar cambios en los datos. Para obtener información sobre cómo configurar la pertenencia y sobre las formas de autorizar a los usuarios a realizar tareas en el sitio, vea Agregar seguridad y pertenencia a un sitio de páginas web de ASP.NET.

  1. En el sitio web, cree una subcarpeta denominada images.

  2. Copie uno o varios archivos .jpg en la carpeta images .

  3. En la raíz del sitio web, cree un nuevo archivo denominado FileDelete.cshtml.

  4. Reemplace el contenido existente por lo siguiente:

    @{
        bool deleteSuccess = false;
        var photoName = "";
        if (IsPost) {
            photoName = Request["photoFileName"] + ".jpg";
            var fullPath = Server.MapPath("~/images/" + photoName);
    
            if (File.Exists(fullPath))
            {
                    File.Delete(fullPath);
                    deleteSuccess = true;
            }
        }
    }
    <!DOCTYPE html>
    <html>
      <head>
        <title>Delete a Photo</title>
      </head>
      <body>
        <h1>Delete a Photo from the Site</h1>
        <form name="deletePhoto" action="" method="post">
          <p>File name of image to delete (without .jpg extension):
          <input name="photoFileName" type="text" value="" />
          </p>
          <p><input type="submit" value="Submit" /></p>
        </form>
    
        @if(deleteSuccess) {
            <p>
            @photoName deleted!
            </p>
            }
      </body>
    </html>
    

    Esta página contiene un formulario donde los usuarios pueden escribir el nombre de un archivo de imagen. No es necesario que introduzcan la extensión del nombre de archivo .jpg; al restringir de esta manera el nombre de archivo, ayudas a evitar que los usuarios eliminen archivos arbitrarios en tu sitio.

    El código lee el nombre de archivo que el usuario ha escrito y, a continuación, construye una ruta de acceso completa. Para crear la ruta de acceso, el código usa la ruta de acceso del sitio web actual (como devuelve el Server.MapPath método ), el nombre de la carpeta images , el nombre que el usuario ha proporcionado y ".jpg" como una cadena literal.

    Para eliminar el archivo, el código llama al File.Delete método y le pasa la ruta de acceso completa que acaba de construir. Al final del marcado, el código muestra un mensaje de confirmación de que se eliminó el archivo.

  5. Ejecute la página en un explorador.

    Captura de pantalla de la ventana del explorador que muestra la página Eliminar una foto del sitio con un campo para el nombre de archivo y el botón Enviar.

  6. Escriba el nombre del archivo que se va a eliminar y, a continuación, haga clic en Enviar. Si se eliminó el archivo, el nombre del archivo se muestra en la parte inferior de la página.

Permitir que los usuarios carguen un archivo

El FileUpload asistente permite a los usuarios cargar archivos en su sitio web. En el procedimiento siguiente se muestra cómo permitir que los usuarios carguen un único archivo.

  1. Agregue la biblioteca de asistentes web de ASP.NET al sitio web, tal como se describe en Instalación de asistentes en un sitio de páginas web de ASP.NET, si no lo agréguelo anteriormente.

  2. En la carpeta App_Data , cree una carpeta y asígne un nombre UploadedFiles.

  3. En la raíz, cree un nuevo archivo denominado FileUpload.cshtml.

  4. Reemplace el contenido existente de la página por lo siguiente:

    @using Microsoft.Web.Helpers;
    @{
        var fileName = "";
        if (IsPost) {
            var fileSavePath = "";
            var uploadedFile = Request.Files[0];
            fileName = Path.GetFileName(uploadedFile.FileName);
            fileSavePath = Server.MapPath("~/App_Data/UploadedFiles/" +
              fileName);
            uploadedFile.SaveAs(fileSavePath);
        }
    }
    <!DOCTYPE html>
    <html>
        <head>
        <title>FileUpload - Single-File Example</title>
        </head>
        <body>
        <h1>FileUpload - Single-File Example</h1>
        @FileUpload.GetHtml(
            initialNumberOfFiles:1,
            allowMoreFilesToBeAdded:false,
            includeFormTag:true,
            uploadText:"Upload")
        @if (IsPost) {
            <span>File uploaded!</span><br/>
        }
        </body>
    </html>
    

    La sección principal de la página usa el FileUpload asistente para crear el cuadro de carga y los botones que probablemente te resulten familiares.

    Captura de pantalla de la página del explorador web Carga de archivos que muestra el selector de archivos auxiliar de carga de archivos y el botón Cargar.

    Las propiedades que establezca para el FileUpload asistente especifican que desea que un único cuadro para que el archivo se cargue y que desee que el botón enviar lea Cargar. (Agregará más cuadros más adelante en el artículo).

    Cuando el usuario hace clic en Cargar, el código de la parte superior de la página obtiene el archivo y lo guarda. El Request objeto que se usa normalmente para obtener valores de los campos de formulario también tiene una Files matriz que contiene el archivo (o archivos) que se han cargado. Puede obtener archivos individuales de posiciones específicas en la matriz( por ejemplo, para obtener el primer archivo cargado, obtener Request.Files[0], para obtener el segundo archivo, obtener Request.Files[1], y así sucesivamente. (Recuerde que en la programación, el recuento suele comenzar en cero).

    Cuando captura un archivo cargado, lo coloca en una variable (aquí, uploadedFile) para que pueda manipularlo. Para determinar el nombre del archivo cargado, solo tiene que obtener su FileName propiedad. Sin embargo, cuando el usuario carga un archivo, FileName contiene el nombre original del usuario, que incluye toda la ruta de acceso. Podría tener este aspecto:

    C:\Users\Public\Sample.txt

    Pero no quiere toda esa información del camino, ya que esa es la ruta en el equipo del usuario, no para el servidor. Solo quiere el nombre de archivo real (Sample.txt). Puede extraer solo el archivo de una ruta de acceso utilizando el método Path.GetFileName, de la siguiente manera:

    Path.GetFileName(uploadedFile.FileName)
    

    El Path objeto es una utilidad que tiene una serie de métodos como este que se pueden usar para quitar rutas, combinar rutas, etc.

    Una vez que haya obtenido el nombre del archivo cargado, puede crear una nueva ruta de acceso para dónde desea almacenar el archivo cargado en su sitio web. En este caso, combinará Server.MapPath, los nombres de carpeta (App_Data/UploadedFiles) y el nombre de archivo recién quitado para crear una nueva ruta de acceso. A continuación, puede llamar al método del archivo cargado SaveAs para guardar efectivamente el archivo.

  5. Ejecute la página en un explorador.

    Captura de pantalla de la página del navegador web del ejemplo de carga de un solo archivo que muestra el selector de archivos y el botón Cargar.

  6. Haga clic en Examinar y, a continuación, seleccione un archivo para cargarlo.

    Captura de pantalla de la ventana Explorador de archivos que muestra un archivo seleccionado y resaltado en azul y el botón Abrir resaltado en un rectángulo azul.

    El cuadro de texto situado junto al botón Examinar contendrá la ruta de acceso y la ubicación del archivo.

    Captura de pantalla de la página del explorador web Ejemplo de carga de archivo único que muestra el selector de archivos con el archivo seleccionado y el botón Cargar.

  7. Haga clic en Cargar.

  8. En el sitio web, haga clic con el botón derecho en la carpeta del proyecto y, a continuación, haga clic en Actualizar.

  9. Abra la carpeta UploadedFiles . El archivo que cargó se encuentra en la carpeta .

    Captura de pantalla de la jerarquía de carpetas del proyecto que muestra el archivo samples dot t x t resaltado en azul dentro de la carpeta Archivos cargados.

Permitir que los usuarios carguen varios archivos

En el ejemplo anterior, permite que los usuarios carguen un archivo. Pero puede usar el FileUpload asistente para cargar más de un archivo a la vez. Esto resulta útil para escenarios como cargar fotos, donde cargar un archivo a la vez es tedioso. (Puede leer sobre cómo cargar fotos en Trabajar con imágenes en un sitio de páginas web de ASP.NET). En este ejemplo se muestra cómo permitir que los usuarios carguen dos a la vez, aunque puede usar la misma técnica para cargar más de eso.

  1. Agregue la biblioteca de asistentes web de ASP.NET al sitio web, tal como se describe en Instalación de asistentes en un sitio de páginas web de ASP.NET, si aún no lo ha hecho.

  2. Cree una página denominada FileUploadMultiple.cshtml.

  3. Reemplace el contenido existente de la página por lo siguiente:

    @using Microsoft.Web.Helpers;
    @{
      var message = "";
      if (IsPost) {
          var fileName = "";
          var fileSavePath = "";
          int numFiles = Request.Files.Count;
          int uploadedCount = 0;
          for(int i =0; i < numFiles; i++) {
              var uploadedFile = Request.Files[i];
              if (uploadedFile.ContentLength > 0) {
                  fileName = Path.GetFileName(uploadedFile.FileName);
                  fileSavePath = Server.MapPath("~/App_Data/UploadedFiles/" +
                    fileName);
                  uploadedFile.SaveAs(fileSavePath);
                  uploadedCount++;
              }
           }
           message = "File upload complete. Total files uploaded: " +
             uploadedCount.ToString();
       }
    }
    <!DOCTYPE html>
    <html>
        <head><title>FileUpload - Multiple File Example</title></head>
    <body>
        <form id="myForm" method="post"
           enctype="multipart/form-data"
           action="">
        <div>
        <h1>File Upload - Multiple-File Example</h1>
        @if (!IsPost) {
            @FileUpload.GetHtml(
                initialNumberOfFiles:2,
                allowMoreFilesToBeAdded:true,
                includeFormTag:true,
                addText:"Add another file",
                uploadText:"Upload")
            }
        <span>@message</span>
        </div>
        </form>
    </body>
    </html>
    

    En este ejemplo, el FileUpload asistente en el cuerpo de la página está configurado para permitir que los usuarios carguen dos archivos de forma predeterminada. Dado que allowMoreFilesToBeAdded se establece en true, el auxiliar representa un vínculo que permite al usuario agregar más cajas de subida.

    Captura de pantalla de la página del navegador web de ejemplo de carga de múltiples archivos que muestra dos selectores de archivos y un botón cargar.

    Para procesar los archivos que carga el usuario, el código usa la misma técnica básica que usó en el ejemplo anterior: obtenga un archivo de Request.Files y guárdelo. (Incluye los distintos pasos que debe seguir para obtener el nombre de archivo y la ruta de acceso correctos). La innovación esta vez es que el usuario podría cargar varios archivos y no sabe cuántos. Para averiguarlo, puede obtener Request.Files.Count.

    Con este número a mano, puede recorrer Request.Files, capturar cada archivo a su vez y guardarlo. Cuando desee recorrer un número conocido de veces a través de una colección, puede usar un for bucle, de la siguiente manera:

    for(int i =0; i < numFiles; i++) {
        var uploadedFile = Request.Files[i];
        if (uploadedFile.ContentLength > 0) {
            fileName = Path.GetFileName(uploadedFile.FileName);
    
        // etc.
    }
    

    La variable i es solo un contador temporal que pasará de cero a cualquier límite superior que establezca. En este caso, el límite superior es el número de archivos. Pero dado que el contador se inicia en cero, como es habitual para los escenarios de recuento en ASP.NET, el límite superior es realmente uno menor que el recuento de archivos. (Si se cargan tres archivos, el recuento es cero a 2).

    La uploadedCount variable totaliza todos los archivos que se cargan y guardan correctamente. Este código tiene en cuenta la posibilidad de que un archivo esperado no pueda cargarse.

  4. Ejecute la página en un explorador. El explorador muestra la página y sus dos cuadros de carga.

  5. Seleccione dos archivos para cargar.

  6. Haga clic en Agregar otro archivo. La página muestra una caja de carga nueva.

    Captura de pantalla de la página del navegador web del ejemplo de carga de múltiples archivos que muestra dos selectores de archivos con archivos seleccionados y un botón Subir.

  7. Haga clic en Cargar.

  8. En el sitio web, haga clic con el botón derecho en la carpeta del proyecto y, a continuación, haga clic en Actualizar.

  9. Abra la carpeta UploadedFiles para ver los archivos cargados correctamente.

Recursos adicionales

Trabajar con imágenes en un sitio de páginas web de ASP.NET

Exportación a un archivo CSV