Requerimiento
Se desea enviar y grabar una imagen en el servidor desde una aplicación Web en ASP .NET, pero antes de enviarla se necesita mostrar el contenido de la imagen el el cliente (Preview).
Solución
Para este fin usaremos FileSystem API de HTML5, en especial la clase FileReader que permite leer un archivo en el cliente y devolver los datos en varios formatos, entre ellos como una URL.
Nota: En muchos sitios, esto lo hacen enviando la imagen al servidor y luego recién hacen el preview, pero si no es la imagen deseada, igual ya se fue hasta el servidor. Lo mejor es hacerlo en el cliente y evitar los envíos innecesarios al servidor web.
Crear la Aplicación Web en ASP .NET Web Form
Crear un "Nuevo Sitio web vacío de ASP .NET" en C# llamado "PreviewImagenFileUpload" y crear las siguientes carpetas:
- Archivos: Para almacenar las imágenes subidas al servidor.
- Paginas: Para contener la pagina de Registro de imágenes.
- Scripts: Para almacenar las rutinas de JavaScript No obstrusivo.
Diseñar la Pagina ASP .NET como un Formulario Web Form
Seleccionar la carpeta "Paginas" y agregar un Formulario Web Form llamado: "Registro.aspx" y escribir el siguiente código:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Registro.aspx.cs" Inherits="Paginas_Registro" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Registro de Fotos</title>
<script src="../Scripts/Rutinas.js"></script>
<script>cargarScriptPagina();</script>
</head>
<body style="background-color:aqua">
<form id="frmRegistro" runat="server">
<div style="text-align:center">
<h1>Preview de Imagen con FileReader al usar FileUpload</h1>
<h2>Registro de Fotos</h2>
<h3>Selecciona la Foto a enviar:
<asp:FileUpload ID="fupFoto" runat="server" />
</h3>
<img id="imgFoto" width="200" height="200" alt="" /><br />
<asp:Button ID="btnEnviar" OnClick="btnEnviar_Click" Text="Enviar" runat="server" />
</div>
</form>
</body>
</html>
Nota: En la sección de Scripts se tiene que definir el archivo de JavaScript que tiene las Rutinas de validación y que realiza el Preview.
El diseño de la pagina se mostrará como en la siguiente figura:
Escribir código JavaScript No obstrusivo para Validar el envío y hacer el Preview
Seleccionar la carpeta "Scripts" y agregar un archivo de JavaScript llamado: "Rutinas.js" y escribir el siguiente código:
window.onload = function () {
var frm = document.getElementById("frmRegistro");
var fup = document.getElementById("fupFoto");
frm.onsubmit = function () {
if (fup.value == "") {
alert("Selecciona un archivo de imagen");
return false;
}
return(true);
}
fup.onchange = function (e) {
var file = e.target.files[0];
if (file != null) {
var extension = file.name.substring(file.name.length - 4, file.name.length);
if (!((extension == ".jpg") || (extension == ".png"))) {
alert("El archivo debe ser jpg o png");
return false;
}
var reader = new FileReader();
if (reader != null) {
reader.onloadend = function () {
var img = document.getElementById("imgFoto");
img.src = reader.result;
};
reader.readAsDataURL(file);
}
else img.src = "No se puede mostrar la imagen";
}
else alert("No se puede mostrar la imagen");
}
}
}
Nota: En el evento "load" de la pagina se valida que se seleccione un archivo antes de enviar al servidor y cuando se selecciona un archivo se valida que sea una imagen jpg o png y se hace el preview usando la clase FileReader del FileSystem API.
Escribir código en el servidor para guardar la imagen en la carpeta Archivos
Escribir el siguiente código C# en la página:
using System;
using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Paginas_Registro : System.Web.UI.Page
{
protected void btnEnviar_Click(object sender, EventArgs e)
{
if (fupFoto.PostedFile.ContentLength > 0)
{
string archivo = Server.MapPath(String.Format("../Archivos/{0}",
Path.GetFileName(fupFoto.PostedFile.FileName)));
if (File.Exists(archivo)) File.Delete(archivo);
fupFoto.PostedFile.SaveAs(archivo);
ClientScript.RegisterStartupScript(this.GetType(), "Mensaje",
"alert('La imagen fue grabada en el servidor');", true);
}
}
}
Nota: Se usa la propiedad "PostedFile" del control FileUpload para obtener el archivo enviado desde el cliente al servidor y lo grabamos en la carpeta Archivos usando su método "SaveAs".
Configurar el permiso de escritura al Usuario de IIS para escribir en la carpeta Archivos
Ingresar al Explorador de Windows y seleccionar la carpeta "Archivos" de nuestro proyecto, luego clic derecho "Propiedades", seleccionar el Tab "Security" y luego clic en el botón "Edit" y luego botón "Add" para agregar al usuario de IIS, si ya existe solo seleccionarlo y luego marcar los checks para darle permiso de escritura y lectura, tal como se muestra en la siguiente figura:
Probar la Pagina Web
Guardar el Sitio Web, clic derecho a la Pagina "Registro.aspx" y seleccionar "Ver en el explorador".
Clic al botón "Enviar" sin seleccionar nada y aparecerá un mensaje de validación que indica que hay que seleccionar un archivo de imagen.
Ahora intenta seleccionar un archivo que no sea un jpg o png, por ejemplo un archivo de texto y se muestra otro mensaje de validación que indica que tiene que ser jpg o png.
Finalmente, selecciona un archivo de imagen png o jpg y clic en "Enviar" y se guarda en el servidor en la carpeta "Archivos" y se muestra un mensaje de confirmación.
Comentario Final
En este post, aprendimos como subir un archivo de imagen al servidor, pero mostrando la imagen antes de enviarla para saber si es la adecuada. Para realizar este preview lo hicimos en el cliente mediante la clase FileReader de HTML5.
Lo interesante es que funciona en la mayoría de Navegadores (Browsers), por lo menos lo probé en IE11 y Chrome 36.
Descarga:
Demo16_Preview_Imagen_FileUpload