martes, 19 de agosto de 2014

El Demo del Día: Preview de Imagen con FileReader al usar FileUpload

Preview de Imagen con FileReader al usar FileUpload

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:

function cargarScriptPagina() {
    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

El Libro del Día: SignalR Real-time Application Cookbook

El Libro del Día: 2014-08-19

Titulo: SignalR Real-time Application Cookbook
Autor: Roberto Vespa
Editorial: Packt
Nro Paginas: 292

Capítulos:
Chapter 1: Understanding the Basics
Chapter 2: Using Hubs
Chapter 3: Using the JavaScript Hubs Client API
Chapter 4: Using the .NET Hubs Client API
Chapter 5: Using a Persistent Connection
Chapter 6: Handling Connections
Chapter 7: Analyzing Advanced Scenarios
Chapter 8: Building Complex Applications
Appendix A: Creating Web Projects
Appendix B: Insights

Descarga:
SignalR_Realtime_Application_Cookbook