miércoles, 3 de marzo de 2010

[ASP.NET] - Guardar Imagen base de datos

 

Introducción


Este articulo tendrá por objetivo demostrar algunas técnicas de tratamiento de archivos cuando es necesario manipularlos para que el cliente desde una página web tenga acceso a ellos.

Entre las operaciones no solo se permitirá la descarga sino que además el cliente podrá subir documentos, y guardar estos en una base de datos.

 

Listar archivos en una carpeta del sitio


Para este trabajo se hará uso del control GridView el cual listara los archivos contenidos en la carpeta del sitio.

Debe remarcarse que siempre que se trabaje con archivos que son subidos o trabajados en el sitio deberá usarse carpetas que estén dentro de la estructura de dicho sitio, no es una buena practica usar rutas como ser c:\, o D:\temp, si el sitio no ha sido creado allí.

public partial class ListarImagenes : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(Server.MapPath("~/files"));
            FileInfo[] fileInfo = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);

            GridView1.DataSource = fileInfo;
            GridView1.DataBind();
        }
    }

    protected void btnSubirArchivo_Click(object sender, EventArgs e)
    {
        if (FileUpload1.HasFile)
        {
            string fullPath = Path.Combine(Server.MapPath("~/files"), FileUpload1.FileName);
            FileUpload1.SaveAs(fullPath);
        }
    }

}

En el evento Page_Load puede observarse como se hace uso de la funcionalidad de System.IO para recuperar el listado de archivos que se encuentran en la carpeta de nombre “files”.

En este caso para poder recuperar el path físico se hace uso de Server.MapPath(), y se referencia la ruta mediante ~/ ya que al encontrarse la carpeta en un nivel distinto es necesario hace referencia desde el root del sitio, en este caso usar ../file también hubiera funcionado.

Al ejecutar la pagina ~/ListarArchivos/ListarImagenes.aspx, se visualizara un resultado como el siguiente:

Imagen1

La grilla toma los valores de las propiedades del objeto FileInfo, es por eso que se hace uso de nombres como Name o Length para mostrar la información de la tabla.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
    ForeColor="#333333" GridLines="None">
    <RowStyle BackColor="#EFF3FB" />
    <Columns>
        <asp:TemplateField HeaderText="Nombre Archivo">
            <ItemTemplate>
                <asp:HyperLink ID="nombre" runat="server" NavigateUrl='<%# Eval("Name", "~/files/{0}") %>'
                    Text='<%# Eval("Name") %>'>
                </asp:HyperLink>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Length" HeaderText="Tamaño" />
        <asp:TemplateField HeaderText="Descargar">
            <ItemTemplate>
                <asp:HyperLink ID="descarga" runat="server" NavigateUrl='<%# Eval("Name", "~/ListarArchivos/Download.aspx?filename={0}") %>'>
                       <img src="../imagenes/download.gif" alt="" width="30px" height="30px" style="border-width:0px;" />
                </asp:HyperLink>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
    <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
    <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
    <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
    <EditRowStyle BackColor="#2461BF" />
    <AlternatingRowStyle BackColor="White" />
</asp:GridView>

Además debe diferenciarse entre los dos link visualizados en la grilla, ya que estos trabajan de distintas formas,

-el primero es un link ordinario que apunta directo al archivos en la carpeta,

-el segundo es un link que fuerza la descarga del archivo a la PC del usuario, para su pre-visualización o guardar en disco.

Es interesante analizar el segundo caso, para este se hace uso de una pagina adicional que recibe como parámetro por QueryString el nombre del archivos.

Esta pagina buscara este valor pasado por parámetro en la carpeta del sitio donde se alojan las imágenes, y mediante el uso del objeto Response pondrá el archivo como respuesta del cliente.

La pagina que realiza esta tareas, es ~/ListarArchivos/Download.aspx :

public partial class Download : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string filename = Request.QueryString["filename"].ToString(); 

        Response.Clear();
        Response.AddHeader("content-disposition", string.Format("attachment;filename={0}", filename));

        switch (Path.GetExtension(filename).ToLower())
        {
            case ".jpg":
                Response.ContentType = "image/jpg";
                break;
            case ".gif":
                Response.ContentType = "image/gif";
                break;
            case ".png":
                Response.ContentType = "image/png";
                break;
        }

        

        Response.WriteFile(Server.MapPath(Path.Combine("~/files", filename)));

        Response.End();

    }
}

De esta pagina se detecta al tipo de archivo mediante la extensión, especificando el ContentType correcto, debe remarcarse que esta técnica no solo funcionaria con documentos de imágenes, si el en futuro es necesario adaptarlo para la descarga de otro tipo de archivos, solo será cuestión de agregar el soporte a nuevas extensiones en el switch.

 

Subir Imágenes a una Base de Datos


Subir una imagen que será persistida en un campo en una base de datos requerirá de algunas vueltas mas en el procesamiento del archivo que es subido al servidor.

Para esto se ha creado una clase que actuara a manera de Data Access y contendrá las consultas que inserten la información en la tabla.

Para guardar la información se hará uso del siguiente método

public static void GuardarImagen(string nombrearchivo, int length, byte[] imagen)
{
    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {
        conn.Open();

        string query = @"INSERT INTO Imagenes (nombre, length, imagen)
                         VALUES (@name, @length, @imagen)";
        
        SqlCommand cmd = new SqlCommand(query, conn);
        
        cmd.Parameters.AddWithValue("@name", nombrearchivo);
        cmd.Parameters.AddWithValue("@length", length);

        SqlParameter imageParam = cmd.Parameters.Add("@imagen", System.Data.SqlDbType.Image);
        imageParam.Value = imagen;

        cmd.ExecuteNonQuery();

    }

}

la pagina ~/GuardarImagen/SubirImagen.aspx  contiene un control FileUpload que seleccionara el archivo a subir en el cliente y mediante un botón se realizara la siguiente acción:

protected void btnGuardar_Click(object sender, EventArgs e)
{

    if (FileUpload1.HasFile)
    {
        using (BinaryReader reader = new BinaryReader(FileUpload1.PostedFile.InputStream))
        {
            byte[] image = reader.ReadBytes(FileUpload1.PostedFile.ContentLength);

            ImagenesDAL.GuardarImagen(FileUpload1.FileName, FileUpload1.PostedFile.ContentLength , image);
            
        }

        CargarListadImagenes();
    }
    

}

Como puede visualizarse en el código se toma la información proveniente del upload y se invoca al método creado en el paso previo para insertar el registro, a este método se le pasa la imagen como un array de byte.

 

Listar archivos desde la base de datos


Bien ahora toca el momento de mostrar la información que es subida en el paso previo, para ello nuevamente se dispone de un GridView que es cargada en el Page_Load

public partial class SubirImagen : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            CargarListadImagenes(); 
    }

    

    private void CargarListadImagenes()
    {
        GridView1.DataSource = ImagenesDAL.GetImagenList();
        GridView1.DataBind(); 
    }

}

Lo interesante de este código esta en la línea 13, en donde nuevamente se hace uso de de un método provisto por la clase de acceso a datos.

public static List<Imagenes> GetImagenList()
{
    List<Imagenes> lista = new List<Imagenes>();

    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {
        conn.Open();

        string query = @"SELECT Id, Nombre, Length  
                            FROM Imagenes";

        SqlCommand cmd = new SqlCommand(query, conn);

        SqlDataReader reader = cmd.ExecuteReader();

        while (reader.Read())
        {
            Imagenes img = new Imagenes(
                                    Convert.ToInt32(reader["Id"]),
                                    Convert.ToString(reader["nombre"]),
                                    Convert.ToInt32(reader["length"]));
            lista.Add(img);
        }

    }

    return lista;

}

 

Este método tiene algo particular devuelve una lista de un tipo de nombre “Imagenes”, la cual resulta ser una clase custom creada para hacer mas simple trabajar con la información obtenida en la consulta.

public class Imagenes
{
    public Imagenes(int id, string nombre, int length)
    {
        this.Id = id;
        this.Nombre = nombre;
        this.Length = length;
    }
    public int Id { get; set; }
    public int Length { get; set; }
    public string Nombre { get; set; }

    public byte[] Imagen { get; set; }
}

El control de grilla hará uso de las propiedades de esta clase para mostrar la información

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
    ForeColor="#333333" GridLines="None">
    <RowStyle BackColor="#EFF3FB" />
    <Columns>
        <asp:BoundField DataField="Nombre" HeaderText="Nombre Archivo" />
        <asp:BoundField DataField="Length" HeaderText="Tamaño" />
        <asp:TemplateField HeaderText="Descargar">
            <ItemTemplate>
                <asp:HyperLink ID="descarga" runat="server" NavigateUrl='<%# Eval("Id", "~/GuardarImagen/Download.aspx?id={0}") %>'>
                       <img src="../imagenes/download.gif" alt="" width="30px" height="30px" style="border-width:0px;" />
                </asp:HyperLink>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
    <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
    <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
    <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
    <EditRowStyle BackColor="#2461BF" />
    <AlternatingRowStyle BackColor="White" />
</asp:GridView>

 

En esta oportunidad hay un detalle a remarcar en cuanto a la descarga, o acceso a la imagen desde el sitio, existen dos formas de tratar el archivo

- por medio de una pagina que reciba el id del registro que contiene la imagen

- por medio de un hadler de asp.net

 

Descargar la imagen por medio de una pagina


En los tag que forman el GridView seguro se ha observado que el link de descarga apunta a una url : ~/GuardarImagen/Download.aspx?id={0}

este es el documento que tomara el id informado por QueryString, realizaría la consulta tomando el archivo de imagen y lo pondrá en el objeto Response listo para enviarlo al cliente.

public partial class Download : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        int id = Convert.ToInt32(Request.QueryString["id"]);

        Imagenes imagen = ImagenesDAL.GetImagenById(id);

        Response.Clear();
        Response.AddHeader("content-disposition", string.Format("attachment;filename={0}", imagen.Nombre));

        switch (Path.GetExtension(imagen.Nombre).ToLower())
        {
            case ".jpg":
                Response.ContentType = "image/jpg";
                break;
            case ".gif":
                Response.ContentType = "image/gif";
                break;
            case ".png":
                Response.ContentType = "image/png";
                break;
        }

        Response.BinaryWrite(imagen.Imagen);
        Response.End();

    }
}

Es interesante remarcar que aquí se hace uso de otro método de la clase de acceso a datos, en este caso para tomar solo la información de una imagen.

 

public static Imagenes GetImagenById(int Id)
{
    Imagenes img = null;

    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {
        conn.Open();

        string query = @"SELECT Id, Nombre, Length, Imagen
                        FROM Imagenes
                        WHERE Id = @id";

        SqlCommand cmd = new SqlCommand(query, conn);
        cmd.Parameters.AddWithValue("@id", Id);

        SqlDataReader reader = cmd.ExecuteReader();

        if (reader.Read())
        {
            img = new Imagenes(
                            Convert.ToInt32(reader["Id"]),
                            Convert.ToString(reader["nombre"]),
                            Convert.ToInt32(reader["length"]));

            img.Imagen = (byte[])reader["Imagen"];

        }

    }

    return img;

}

Descargar la imagen por medio de un handler


Si bien el código interno que usara el handler será igual al de la pagina, este requieres algunos comentarios.

El primero es que a modo de ejemplo el uso de handler se desarrollo en la pagina ~/GuardarImagen/ListarImagenes.aspx

Esta pagina posee una grilla en donde una de las columnas hay un control de imagen:

    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        CellPadding="4" ForeColor="#333333" GridLines="None">
    <RowStyle BackColor="#EFF3FB" />
    <Columns>
        <asp:BoundField HeaderText="Nombre" DataField="nombre"  />
        <asp:TemplateField HeaderText="Imagen">
            <ItemTemplate>
                <img alt="" src="<%# Eval("Id", "Image.ashx?id={0}") %>" width="200px" height="200px" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
    <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
    <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
    <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
    <EditRowStyle BackColor="#2461BF" />
    <AlternatingRowStyle BackColor="White" />
</asp:GridView>

la línea importante es

<img alt="" src="<%# Eval("Id", "Image.ashx?id={0}") %>" width="200px" height="200px" />

en esta se hace uso de un nombre y extensión especifico, en realidad lo importante es la extensión, el nombre en este caso puede ser cualquier otro y seguiría funcionando.

La imagen en este caso esta utilizando un handler para cargar la imagen, el mismo esta en la clase: HttpImageHandler.cs

public class HttpImageHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        int id = Convert.ToInt32(context.Request.Params["id"]);

        Imagenes imagen = ImagenesDAL.GetImagenById(id);

        context.Response.Clear();
        context.Response.AddHeader("content-disposition", string.Format("attachment;filename={0}", imagen.Nombre));

        switch (Path.GetExtension(imagen.Nombre).ToLower())
        {
            case ".jpg":
                context.Response.ContentType = "image/jpg";
                break;
            case ".gif":
                context.Response.ContentType = "image/gif";
                break;
            case ".png":
                context.Response.ContentType = "image/png";
                break;
        }

        context.Response.BinaryWrite(imagen.Imagen);
        context.Response.End();
    }

    public bool IsReusable
    {
        get { return false; }
    }

}

Lo interesando te este código es que al igual que la pagina de descarga, se tiene acceso al objeto Reponse, solo que en esta oportunidad es a través de HttpContext.

Además debe tenerse en cuenta para que el handler funcione es necesario agregar una línea en el archivo web.config

en este debería agregarse:

<add verb="*" path="*.ashx" type="GuardarImagenBaseDatos.GuardarImagen.HttpImageHandler"/>

El atributo type debe incluir todo el namespace, mas el nombre de la clase, debe tenerse en cuenta que esto puede variar en cada desarrollo dependiendo de donde se ubique la clase del handler.

Aclaración


Para que el ejemplo funcione es necesario contar con Sql Server Express instalado en la PC donde se ejecute el código, y el servicio debe estar iniciado

[C#]
[VB.NET]

168 comentarios:

nsperez dijo...

Exelente articulo me sirvio mucho para guardar archivos en la BD cargandolos desde Fileupload, el unico inconveniente es que no esta la opcion para recuperar el archivo desde la BD.

Gracias por el aporte

Leandro Tuttini dijo...

hola nsperez

que bueno que sea util el articulo

bien te comento que esto que consultas este implementado, no se si has visto:

ImagenesDAL.GetImagenById()

alli uso esta linea:

img.Imagen = (byte[])reader["Imagen"];

la cual devuelve un array de byte que representa el binario de la imagen, pasar esto a un tipo Image si es que lo necesitas no es dificil

podrias hacer:


public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}

despues este si quieres lo grabas como imagen al disco, aunque tambien el byte[] directo se podria haber guardado a disco si se queria.


saludos

Edalo dijo...

Disculpa estoy tratando de abrir el ejemplo pero al ejecutarlo me sale un error que dice algo como esto :"No se puede abrir la base de datos 'C:\DOCUMENTS AND SETTINGS\LINARES\ESCRITORIO\[VB.NET]GUARDARIMAGENBASEDATOS\GUARDARIMAGENBASEDATOS\APP_DATA\ARCHIVOS.MDF' en la versión 655. Este servidor es compatible con la versión 611 y anteriores. No se admite esta ruta de actualización. No se puede abrir la nueva base de datos 'C:\DOCUMENTS AND SETTINGS\LINARES\ESCRITORIO\[VB.NET]GUARDARIMAGENBASEDATOS\GUARDARIMAGENBASEDATOS\APP_DATA\ARCHIVOS.MDF'. CREATE DATABASE cancelada. Error al intentar adjuntar una base de datos nombrada automáticamente para el archivo C:\Documents and Settings\Linares\Escritorio\[vb.net]GuardarImagenBaseDatos\GuardarImagenBaseDatos\App_Data\Archivos.mdf. Ya existe una base de datos con el mismo nombre, no se puede abrir el archivo especificado o se encuentra en un recurso compartido UNC.".
En que version de sql esta hecho?? En 2008?? porque yo tengo instalada la 2005, alguna sugerencia para solucionar este problema ?? :(

Leandro Tuttini dijo...

hola Edalo

Asi es, el ejemplo fue creando usando Sql Server Express 2008.

Se me ocurre que podrias probar attachando directamente la db al servicio de sql server, usando para esto el Sql Server Management Studio.
Igual no estoy seguro si aqui detectara tambien la version con que fue creada la db, puede que sea mas permisivo, pero la verdad nunca lo probe, ya que hace tiempo deje de usar sql server 2005.

Recuerda ademas, si lo anterior funciona, que debes cambiar el ConnectionString del web.config, para que se conecte al servicio de sql server, y no realice un attach dinamico de la db.


saludos

Fatima dijo...

Hola mi estimado la verdad que esta muy bueno este articulo, no se si me puedes ayudar es que quiero subir unos archivos .doc y que se visualicen en una pagina asp.net vb pero no quiero que se descargen solo que se muestren asi como un visor de documentos, queria implementarlo con el xmldatasource pero me es mas complicado haber si me das una mano gracias.

Leandro Tuttini dijo...

hola Fatima

Se me ocurren algunas alternativas, pero todas implcian que el usuario que accede al sitio tenga office instalado en su equipo, ya que sera al asociacion del tipo de documento vinculado con el IE lo que proporciona al visualizacion

- una alterntiva podria ser que lances un popup de una ventana usando window.open() desde javascript indicando en al url el archivo de word.
Esto deberia mostrarlo en esa ventana.

- la otra seria que uses un tag IFRAME de html para que dentro indiques el archivo de word que quieres visualizar

El problema pasa porque no hay un control para la web (no al menos de libre uso, pago puede que exista) que permita al visualizacion de documentos, sino que es la asociacion de la extension .doc con la aplicacion de Office Word, la que posibilita dicha visualizacion.

Si el usuario cambia la aplicacion por defecto para visializar el word puede que se vea integrado al IE con esta nueva aplicacion, o que pida la descarga del archivo.

Bueno espero sean de utilidad estos consejos
saludos

Richof dijo...

Hola Leandro, me sería muy util si pudieras aumentar al ejemplo, una columna tipo imagen al gridview en GuardarImagen.SubirImagen.aspx y mostrar la imagen que se acaba de subir a la BD y todas las existentes y lo mismo en ListarArchivos.ListarImagenes.aspx que si no me equivoco, es cuando se usa la tecnica de subir imagenes a un directorio.
Saludos

Leandro Tuttini dijo...

hola Richof

Disculpa la tardanza en la repuesta

Viendo el tema no creo haber entendido del todo cual seria el cambio, o ampliacion, del ejemplo

Ya que no aplique ninguna tecnica para determinar cuales imagenes son rcientes y cuales no como para diferenciarlas.

El ejemplo basicamente sube una imagen al servidor y luego la lista, pero no la marca como nueva, para diferenciarla del resto

saludos

Yeison Andres Manco Quiroz dijo...

Leandro, buenas tardes,
Tengo una duda el código que se agrega en el web.config depende de que? pues es que no entiendo la ruta imagenes.guardarimagen.httphandler ?
Gracias

Yeison Andres Manco Quiroz dijo...

Ya sé a que se refiere al namespace seguido del nombre de la clase.

Lo estoy haciendo igual pero me sale este error Línea 69:

La clase se llama Thumbnail y el archivo se llama imagen.aspx
Afecta en algo?

Gracias

Yeison Andres Manco Quiroz dijo...

EL ERROR ES ESTE
Línea 69:
add verb="*" path="*.ashx" type="Coldetec.Thumbnail"

Yeison Andres Manco Quiroz dijo...

que pena este
: No se pudo cargar el tipo 'Coldetec.Thumbnail'.

Leandro Tuttini dijo...

hola Yeison

Recuerda que cuando armes el type este debe incluir el nombre completo de la clase.

Para esto revisa la parte del Assembly Name imagen
para validar que ese sea el nombre completo, como veras en el ejemplo es algo mas largo del que has usado, por ahi falto algun namespace.

saludos

fixertool dijo...

Hola Leandro. Me interesa mucho este artículo, y en este momento estoy enfrentado a un inconveniente.
Deseo implementar un handler para mostrar thumbnails en una columna de un gridview.
Ya tengo las imágenes correctamente cargadas, algo que comprobe al cargar alguna en un PictureBox.
Todas las imágenes están en una tabla que además guarda otros datos de estos thumbnails que son fotos de autos: cada auto tiene su id, modelo, año, fabricante, etc.
Hago la consulta, y el bind en la grilla, mostrándose los datos mencionados.
Me está faltando mostrar las imágenes en su respectiva columna, a las que identifico por el id.
Si yo ya tengo cargado un datatable con toda la info, ¿cómo puedo evitar una nueva consulta dentro del Handler?
Es decir, al handler le paso el id por query. ¿Qué tendría que hacer? ¿Guardar el datatable en una sesión, y acceder por Item?
O es inevitable que haga otra consulta dentro del handler, reabriendo una conexión que ya está abierta (con la que cargo el datatable mencionado)
Muchas gracias por tu tiempo.

Leandro Tuttini dijo...

hola fixertool

Podrias dentro de handler realziar solo una vez la consulta a la db y guardar los registros en Session para que en sucesivos accesos no tengas que realzia el query nuevamente, sino que lo recuperas directo del DataSet (o DataTable)

Dentro del Handler seguro necesites usa el context.Session
para poder dejar el datatabel alli, en los siguientes acceso deberias preguntar si la Session tiene o no datos, sino los tienes entonces lanzas la query.

if(context.Session["datos"] == null){
//aqui realzias la consulta y cargas el datatable
context.Session["datos"] = dt;
}
//aqui tomas la imagen del datatable

Para acceder a un registro del datatable por ahi necesites el

DataTable.Select (Método) (String)

En tu caso filtrando por el id que proporcionas en el handler.

saludos

Fabian dijo...

Gracias por tu respuesta. Al final logré recuperar los thumbnails de la base de datos y mostrarlos en la grilla, en los rows correspondientes según id. Más tarde optimizaré según tu sugerencia.
Me pregunto si habiendo recuperado de esta forma las imágenes (thumbnails), podré mostrar mediante click en el thumbnail, y usando lightbox, las imágenes en tamaño grande. A estas imágenes también las tengo guardadas en la misma tabla, asociadas mediante id.

Leandro Tuttini dijo...

hola Fabin

Me alegro que hayas podido visualizar las imagenes.

La verdad no he aplicado esta tecnica junto al lightbox, pero imagino que no deberia haber problema ya que en definitiva lo que se recibe es la imagen en el cliente y llega de la misma forma que al solicitar un archivo, o sea un array de byte, solo que con el handler uno tiene el control de los byte enviados, al invocar un archivo de imagen este se envia sin intervencion alguna al cliente.

Por ahi esto resulte util para tu aplciacion:
Visual jQuery LightBox

saludos

maestro dijo...

Me gusto mucho esta aplicacion de Guardar imagen base de datos, me gustaria publicara alguna aplicacion donde se manejen videos desde una base de datos access en windows form en c#; Se lo agradeceria mucho.

Leandro Tuttini dijo...

hola maestro

Videos desde una db Access, lo veo algo poco performante, no creo que Access como base de datos este preparada para soportar video.

Si bien Sql Server podria alojar este tipo de archivos, creo que tampoco seria una buena opcion, ya que los videos de por si requieren una reproduccion un tanto especial, mas si hablamos de videos de varios megas.

Habria que pensar en alguna tecnica que envie streaming

Streaming

saludos

Fabian dijo...

Todo anda bien (muestra imágenes desde la BD, anda bien el lightbox) Pero se me presenta un detalle. La columna de imagen está definida de forma parecida a tu anteúltima imagen de código, con dos diferencias: el tag img está embebido en un anchor, para poder relacionarla con el handler (y el lightbox adicional) que retorna la imagen full size.

Y la otra es que al final decidí cargar una imagen genérica, en lugar de los thumbnails asociados al registro, por razones de performance (para aclarar, pongamos que puse una imagen que dice "haga click aquí").
Pero no todos los registros tienen imagen asociada. En ese caso, quiero que se vea otra imagen, que advierta de que no hay imagen full size disponible. Y, sobre todo, que quede deshabilitado el anchor para que no se dispare el lightbox. O en caso de que no lo hubiera, para que no siga un enlace que de hecho no retornaría nada.
Tricky, Huh? ¿Cómo se puede manejar esta situación?

Leandro Tuttini dijo...

hola Fabian

En este caso creo que el tema lo resuelves directo desde los datos cuando bindeas el control que arma el thumbnails, no se si sera un gridview, o algun otro.

La idea es que de alguna forma en la query que usas para cargar la lista de imagenes puedas enviar un campo que indique si ese registro tiene o no imagen asociada, entocnes en el <# Bind> o en el RowDatabound, apliques la logica que valide ese campo y mostrar el link a una image o a otra, en realidad lo ideal seria que deshabilites la url o el link, sino hay imagen, para que no se pueda pulsar.

Pera la idea es que por medio de un left join entres las tablas puedas unir la entidad con la imagen y enviar un valor qeu indique si hay imagen

SELECT P.id, P.producto, COUNT(I.Id) as CantImagenes
FROM Productos P LEFT JOIN Imagenes I
ON P.Id = I.Id
GROUP BY P.id, P.producto

Si la cantidad de imagenes devuelve un valor mayor a cero entonces tiene y por lo tanto muestras el link

Tambien podrias probar algo como esto

SELECT P.id, P.producto, IIf(COUNT(I.Id) > 0, 1, 0) as CantImagenes
FROM Productos P LEFT JOIN Imagenes I
ON P.Id = I.Id
GROUP BY P.id, P.producto

Para que solo devuelva cero o uno si hay o no imagen.

saludos

Fabian dijo...

Agradezco mucho tu respuesta. Te comento como lo resolví. No fue necesario el left join, ya que uno de los campos de la tabla me indicaba si había sido cargada la imagen. Y aunque no lo hubiera, me alcanzaba con preguntar si el campo de tipo imagen estaba en NULL.
En cuanto a lo otro, lo solucioné con el evento RowDataBound del gridview.
Si bien muestro una imagen de advertencia para cuando no hay archivo de imagen asociado al registro, no pude deshabilitar el link. Eso no me preocupa, ya que si el usuario igual hace click, al abrir el lightbox se verá esa misma imagen de advertencia.
Pongamos que en lugar de lightbox hubiese redirigido a otra página, entonces habría mostrado los datos, y punto.
Muchas gracias por tu tiempo.

julito dijo...

Hola Leandro muy buenio el ejemplo, mira que quiero saber que tipo de dato es el campo Imagen en la base de datos, pero no he podido verla... no se si tengas el script o me puedas ayudar con eso

Grcias

Leandro Tuttini dijo...

hola julito

La imagen se persiste en un campo del tipo "Image" en la tabla

Aunque si usas uno del tipo varbinary(MAX) tambien es valido

Data Types (Transact-SQL)

saludos

Marcos dijo...

Hola Leandro:
"public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}

despues este si quieres lo grabas como imagen al disco, aunque tambien el byte[] directo se podria haber guardado a disco si se queria."

Como hago para grabar la imagen a disco? Necesito guardarla a disco para luego poder mostrarla en un control Image1.ImageURL
Gracias

Leandro Tuttini dijo...

hola Marcos

Disculpa la demora de la respuesta

Para grabar a disco lo asm simple es usa la funcionalidad de

File.WriteAllBytes (Método)

En este metodo indicas la ruta completa del archivo que quieres crear, y el array de byte directo (el que representa la imagen), no hace falta que lo conviertas a Image

saludos

Marcos dijo...

Muchas Gracias Leandro
Saludos

ronny dijo...

saludos caballero muy interesante su aporte podria publicar algo similar pero esta vez insertando pdf a mi BD y que estos puedan ser desplegados en mi aplicacion le agradeceria muchisimo si me diera una idea de como hacerlo
gracias...

Leandro Tuttini dijo...

hola ronny

buena idea el fin de semana proximo me hago un rato y armo un ejemplo de esto que planteas,
pero voy a realizarlo para archivos mas variados como ser word, pdf, excel, etc
igual salvo la validacion de la extension la tecnica igual para cualquier archivo

saludos

Leandro Tuttini dijo...

hola ronny

Mira publique el artículo que habia comentado, evalualo a ver si te es de utilidad

[ASP.NET] Grabar Archivo en base de datos

EFRAIN MEJIAS C 11.346.727 Ing.Sistemas-001 dijo...

private void button1_Click(object sender, EventArgs e)
{
try
{

string Cedula, Nombres, Apellidos, Sucursal;DateTime Fecha = dateTimePicker1.Value.Date ;
Cedula = textBox1.Text; Nombres = textBox2.Text; Apellidos = textBox3.Text; Sucursal = textBox4.Text;
Image Imagn = pictureBox1.Image;
SqlConnection cnx = new SqlConnection(@"Data Source=FABRIZIOSERVER1\SQLEXPRESS;Initial Catalog=Cliente;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
cmd.Connection = cnx;
cmd.Connection.Open();
cmd.CommandText = "INSERT INTO Cliente VALUES (@Cedula,@Nombres,@Apellidos,@Sucursal,@Fecha,@Imagn)";
cmd.Parameters.AddWithValue("@Cedula", Cedula);
cmd.Parameters.AddWithValue("@Nombres", Nombres);
cmd.Parameters.AddWithValue("@Apellidos",Apellidos);
cmd.Parameters.AddWithValue("@Sucursal",Sucursal);
cmd.Parameters.AddWithValue("@Fecha",Fecha);

SqlParameter ImageParam = cmd.Parameters .Add ("@Imagn",System.Data.SqlDbType.Image);
ImageParam.Value = Imagn;

cmd.ExecuteNonQuery();
cmd.Connection.Close();
cmd.Parameters.Clear();
MessageBox.Show("LOS DATOS FUERON REGISTRADOS CON EXITO " ,"LISTO");
}
catch (Exception Ex)
{
MessageBox.Show("ERROR " + Ex,"ADVERTENCIA");
}

}

Leandro Tuttini dijo...

hola EFRAIN

No respondi antes porque vi tu pregunta en el foro, asi que imagine que ya lo habias solucionado

http://social.msdn.microsoft.com/Forums/es/vcses/thread/1ade8622-8711-4d31-a6f6-93d1fe1bfc0e


saludos

Ados dijo...

Hola Leandro, he estudiado tu código, la verdad es que es muy util sobre todo la parte de handler, por lo menos es en lo que ya estoy más pez.

Estoy intentando poner una imagen directamente en un control image sin tener que grabar en un fichero en disco, pero no se como asignar el array de byte al control imagen.
¿Debo usar un handler para hacerlo?

muchas gracias

Leandro Tuttini dijo...

hola Ados

Justamente para plantear ese tema cree recientemente un post que podria ayudarte

[ASP.NET] GridView – Edición Empleados

Veras alli como se hace uso del handler para asignar la imagen al control Image


saludos

Edalo dijo...

Hola Leandro, podrías volver a subir el archivo? De un día a otro este y otros archivos han dejado de estar disponibles :(
Gracias

Leandro Tuttini dijo...

hola Edalo

Si, es un tema con el skydrive, se ve que alguna actualizacion que hicieron invalido los links que habia puesto en el articulo.

te dejo el link directo para que lo descargues de este hasta que actualice:

https://skydrive.live.com/?cid=b30e32da2150df24&sc=documents&id=B30E32DA2150DF24!268

saludos

Edalo dijo...

Muchas gracias Leandro, como siempre presto a ayudarnos.
Saludos

Antonio dijo...

Buenas noches Leandro, no se si pudieses subir el script o indicarme solo cual es la estructura de la BD

Gracias de antemano

Leandro Tuttini dijo...

hola Antonio

En realidad no agregue el script porque es solo una tabla

te dejo el script que la crea

CREATE TABLE [Imagenes](
[id] [int] IDENTITY(1,1) NOT NULL,
[nombre] [varchar](50) NOT NULL,
[length] [int] NOT NULL,
[imagen] [image] NOT NULL,
CONSTRAINT [PK_Imagenes] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF

saludos

Antonio dijo...

Muchas gracias Leandro por tu pronta respuesta :D

Shark93 dijo...

Excelente Post Mi Hermano, Fue De Gran Ayuda...

Saludos Desde Colombia.

x4v1er dijo...

Hola

Tengo una duda, yo tengo la base de datos hecha en sql server, quiero que me deje descargar el archivo tipo image almacenado en una base de datos pero en vb.net me muestre las imagenes de acuerdo a dis parametros que le envio es decir, deme la imagen que pertenece al usuario X, del año Y, y del curso Z, que me muestre un link de descarga de la imagen , no se mucho de vb.net ojala me puedas colaborar

Leandro Tuttini dijo...

hola x4v1er

La tecnica a seguir es la misma, creas el hadler encargado de poner en el response el array de byte de la imagen que toma por parametro

solo que en tu caso pasaras en la url 3 parametros, en lugar de solo el id

en el codigo del handler deberias tomar de la url en el querystring los 3 valores que el llegan, hacer la consulta a tu tabla filtrrando por estos y recuperar el registro de la imagen, para luego ponerlo en el Response


saludos

Rafa dijo...

Hola estoy haciendo un metodo en una clase c# en los cuales tengo unos datos `para guardar NOMBRE APELLIDO Y LA IMAGEN pero no se de que tipo poner LA IMAGEN es algo asi

http://chopapp.com/#v0ujgwhq

gracias por su ayuda

Rafa dijo...

quisiera saber de que tipo colocaria IMAGEN pasandola como un parametro..n este link esta el codigo. Es de una clase c# que estoy haciendo para usarla o llamarla en los winforms

gracias



http://chopapp.com/#v0ujgwhq

Leandro Tuttini dijo...

hola Rafa

En el parametro la imagen deberia ser del tipo byte array, o sea byte[]

Si revisas el articulo veras que al usar la instruccion en la query es justamente de este tipo

Recomendaria leas este otro articulo

[WinForms] Edición Empleados – Grabar imagen en base de datos

alli se muestra mucho mejor esto que comento

saludos

Ismael Montes dijo...

Buenas tardes Leandro, perdona que escriba mi comentario en este articulo que ya ha pasado un buen tiempo desde que se publico. Me gustaría saber si existe alguna forma de poder recuperar una imagen guardada en la forma que se explica en tu articulo, pero no guardarla en un directorio sino poder enviarla como archivo adjunto en un correo utilizando sp_send_dbmail de sql server. es decir adjuntar el archivo que de resultado un query.

Leandro Tuttini dijo...

hola Ismael Montes

La verdad nunca he usado el procedure sp_send_dbmail, pero si puedo ver en al documetacion

sp_send_dbmail (Transact-SQL)

que tiene un parametro para esto que necesitas
@query_attachment_filename
aunque veo que este lo que espera es un string con el path al archivo que se adjunta y no un array de byte

quizas se deba bajar primero el byte[] a un archivo fisico antes de enviar el mail

saludos

zenit dijo...

hola oye no podiras mostrar una imagen de tus base de datos creadas

zenit dijo...

hola amigo oye no podrian poner ña imagenes de tu base de datos para comprender un poco mejor te agradeseria mucho

Leandro Tuttini dijo...

hola zenit

el tema es que no hay mucho que mostrar la db solo tiene una tabla unica

revisa la respuesta que le doy a Antonio, ahi puse el script que crea la unica tabla donde registra el ejemplo


saludos

Maximiliano I. Carrasco Araneda dijo...

Estimado tu blog me a servido de mucha ayuda, muchas gracias. Una consulta estoy trabajando con un FileUpload y quisiera que al momento de examinar me abriera una ruta en especial, como puedo hacer esto, llevo dias investigando y no encuentro nada satisfactorio, espero me puedas ayudar, gracias.

Leandro Tuttini dijo...

hola Maximiliano

El tema es que la carpeta que definirias por defecto pertence a la pc del usuario, por temas de seguridad este control no puede acceder a las carpetas ni definir una porque seria un riesgo, una vulnerabilidad

ademas estas en un entorno web como podrias saber de forma global que todos los usaurio de todo el mundo que acceda a un sitio web tendra esa carpeta, no puede por eso no hay forma de definir una por defecto.

Ademas habras visto que cuando selecionas un archivo, no puede acceder a su ruta desde el cliente ni desde el servidor, o sea el path completo tampoco lo puede recuperar

En el cliente creo que la maximo es el nombre del archivo y desde el servidor solo llega el array de byte, justamente porque un ambiente web no puede acceder a las carpetas por si solo, requiere de una accion del usaurio, sino millones de virus estarina haciendo de las suyas

saludos

Maximiliano I. Carrasco Araneda dijo...

Estimado, me dejaste muy claro con el tema una vez mas gracias.

ross junior dijo...

Ola leandro tengo un problema: "No se puede abrir la base de datos 'C:\DOCUMENTS AND SETTINGS\LINARES\ESCRITORIO\[VB.NET]GUARDARIMAGENBASEDATOS\GUARDARIMAGENBASEDATOS\APP_DATA\ARCHIVOS.MDF' en la versión 655. Este servidor es compatible con la versión 611 y anteriores. No se admite esta ruta de actualización. No se puede abrir la nueva base de datos 'C:\DOCUMENTS AND SETTINGS\LINARES\ESCRITORIO\[VB.NET]GUARDARIMAGENBASEDATOS\GUARDARIMAGENBASEDATOS\APP_DATA\ARCHIVOS.MDF'. CREATE DATABASE cancelada. Error al intentar adjuntar una base de datos nombrada automáticamente para el archivo C:\Documents and Settings\Linares\Escritorio\[vb.net]GuardarImagenBaseDatos\GuardarImagenBaseDatos\App_Data\Archivos.mdf. Ya existe una base de datos con el mismo nombre, no se puede abrir el archivo especificado o se encuentra en un recurso compartido UNC.".
y utilizo visual 2008. pero me puedes decir k tipo de valores tienen las columnas gracias

ross junior dijo...

ya solucine ese problema creando una nueva bd pero una pregunta en el campo Imagen k koloko la direccion de la imagen o k por k no e podido gracias

ross junior dijo...

listo ya pude gracias

ross junior dijo...

muy util el codigo me haz salvado mi graduacion :D

Leandro Tuttini dijo...

hola ross junior

te comento que la db que uses para crear el articulo es SqlServer 2008 R2 Express

quizas sino tienes esta version o una superior tengas problemas

en el campo image deberias definirlo como "Image" o tambien deberias funcionar como varbinary(max)

saludos

Carlos Misael dijo...

Excelente !!!

Iris dijo...

Hola Leandro...fue de muy util tu ayuda

Iris dijo...

Hola Leandro fue de muy util sobre como guardar una imagen en la base de datos.....

javier dijo...

y si kiero hacerlo desde el update panel?

Leandro Tuttini dijo...

hola javier

En principio deberia ser lo mismo, ya que el UpdatePanel lo que evita es el refresh de la pagian pero por detras las tecncias de asp.net se consevan

si haces un upload de una imagen, quizas usea el
AsyncFileUpload

pero igual la forma en como grabas en la db y como recuperas la imagen no cambia en nada

saludos

DSInfo dijo...

Hola Leandro, sabes que tengo un handler que funciona bien, o sea lo abre en mi maquina local, cuando subo todo al server, deja de funcionar.

El handler abre a su vez un PDF, en donde vamos completando los campos.

Se te ocurre algo, para saber porque abre el handler en blanco en el server y no asi en la maquina local.

Saludos
Eduardo

p4co0 dijo...

oiee. solo lo baje en c# y al abrirlo.. corre.. osea funciona.. pero no me guarda direcciones en a base da datos. PD no le he movido a nada masque al webconfig.. que cambié los datos por mis datos de logueo en sql.. tengo que crear una bd con tablas o algo asi? o se va insertando todo solo o como.. no entiendo :S

p4co0 dijo...

bueno.. ya tengo la BD que se llama imagen y la tabla que introduje con el script que le dejaste a antonio. a que le tengo que mover para que inserte en mi bd. esta como default no?.. se conecta automaticamente.. pero como hace referencia a la BD.. se hace en el webconfig? esque nunca he echo conexiones a bd y por eso no se mucho del webconfig.. pero pues asi de simple como es la pregunta.. ¿que tengo que cambiar para que se inserte en mi BD? porfavor.. (: y gracias esta muy bueno el post

Leandro Tuttini dijo...

hola DSInfo

de casualidad en el handler defines algun try..catch que pudiera estar atrapando algun error que no se devuelve a la pagina ?

quizas debas ver de agregar codigo de logeo en ese habdler para que registre en un archivo que sucede

cuando dices que el handler abre te refires a que toma el pdf y lo envia en el response al cliente, o sea no es que lo ejecutas, porque si haces esto se abrira en el servidor, no en el cliente

saludos

Leandro Tuttini dijo...

hola p4co0

exacto por medio del web.confign defines la cadena de conexion a la base de datos

lo que debes cambiar para re-apuntar a la db que tu usas es la seccion de





es alli donde debes modificar

saludos

Javier dijo...

Hola, sabes estoy iniciando la programacion en c# y estoy tenuendo problemas para grabar un documento tipo .tiff multipaginas a sql server, ya que al traerlo de nuevo solo veo la primera pagina, a ver si me ayudas, gracias

Leandro Tuttini dijo...

hola Javier

no entendi
o sea cuando grabas envias al campo de la tabla un array de byte, por lo tanto recuperas lo mismo cuando tomas la info de ese campo

por ahi en lugar de usar un tipo de dato image podrias suar un varbinary(max) para ver si el tipo de dato del campo no afecta la imagen, pero igual es raro

saludos

Angel dijo...

Hola Leandro, estoy trabajando en un proyecto el cual necesita mostrar las imagenes directamente en una grilla yo estoy intentando utilizar un gredview, sinceramente tu codigo me a resultado bastante util a la hora de guardar las imagenes como mapa de bits en una base de datos, pero todavia no e podido resolver el problema de que la gredview me muestre las imagenes, estube mirando bastante por internet y las soluciones son para winforms en su mayoria pero no muestran como listar imagenes desde una base de datos a un gredview. Trabajo con un sistema en 3 capas, Persistencia, Logica y Presentacion. My pregunta es; creo un Objeto que tiene Id, Nombre, Length e Imagen de tipo Image como aconsejas en el ejemplo, pero a la hora de mostrar este objeto en un gredview, muestra todos los datos menos la imagen que por sierto es en realidad lo que necesito mostrar. Agradeceria si me pudieras ayudar con este problema, gracias.

Leandro Tuttini dijo...

hola Angel

Porque crear una propiedad en tu objeto de tipo Image, eso no deberia ser asi, debes usar un byte[], la imagen es un array de byte
El image solo se usa para cargar controles o trabajar con la imagen pero si es para enviarla por el Request es solo un array de byte

public byte[] Imagen {get; set;}

en un entorno web olvidate del Image

saludos

Angel dijo...

Hola Leandro muchas gracias por contestar tan rapido, te cuento que tome en cuenta tu ayuda, pero el problema persiste. Voy a intentar ser mas detallado, como te comente tengo un proyecto de 3 capas
Clase Imagenes
private int _id;
private string _nombre;
private int _length;
private byte[] _imagen;

public byte[] Imagen
{
get { return _imagen; }
set {_imagen = value;}
}

public Imagenes(string pNombre, int pLength, byte[] pImagen)
{
_nombre = pNombre;
_length = pLength;
_imagen = pImagen;
}

public Imagenes(int pId, string pNombre, int pLength)
{
_id = pId;
_nombre = pNombre;
_length = pLength;
}

public override string ToString()
{
return (_id.ToString()
+ _nombre.Trim()
+ _length.ToString()
+ _imagen);
}
En logica llamo a la capa Persistencia:
public static List ListarImagen()
{
List oResultado = PersistenciaImagenes.ListarImagen()
return oResultado;
}

Y en persistencia me conecto con la BD para cargar un objeto de tipo Imagen (no incluyo la parte de conexion, ya comprobe que no es ese el problema)

reader = oComando.ExecuteReader();
while (reader.Read())
{
Imagenes oFoto = new Imagenes( Convert.ToInt32(reader["Id"]),
Convert.ToString(reader["nombre"]),
Convert.ToInt32(reader["length"]));
oFoto.Imagen = byte[])reader["Imagen"];
oResultado.Add(oFoto);
}
return oResultado;

Te cuento que segui con F11 paso a paso y logro traer todos los datos desde la BD pero al momento de mostrar me los muestra todos menos la imagen.

el gredview lo cargo asi:
GridView1.DataSource = LogicaImagenes.ListarImagen();
GridView1.DataBind();

Te pido disculpas por haber sido tan extenso y desde ya te agradezco cualquier sugerencia que me pueda ayudar a resolver el problema. Muchas Gracias

Leandro Tuttini dijo...

hola

la definicion de la entidad y la carga desde la persistencia parecen estar correctos, pero el tema es como usas este codigo desde el handler?

analiza el codigo de este articulo y veras que al control Image de asp.net no le asignas el byte[] de forma directa, sino que este lo envias en el Response, por eso el handler

Eso es lo que deberias validar junto al ContentType que definas con el tipo de imagen que envias

saludos

Angel dijo...

Hola Leandro, la verdad muchas gracias, tenias razon me faltaba agregar estas lineas de codigo al webb config:

httpHandlers
add verb="*" path="*.ashx" type="Persistencia.HttpImageHandler
httpHandlers

Con eso pude listar las imagenes en el gredview sin problemas.
Otra vez, Muchas Gracias por la ayuda y por la atencion.
Gracias Saludos

Nesoft dijo...

Gusto en saludarte nuevamente Leandro, espero me puedas ayudar con los siguiente: Se me presenta la oportunidad de resolver un problema con una aplicación que cargar archivos (como maxímo de 3MB) dentro de determinada carpeta en el servidor con el FileUpload, pero los usuarios tienen una conexión lenta a internet y el timeout les corta la subida de los archivos, las preguntas son, ¿Subir los archivos por FTP es buena opción?,¿Cuál consideras que sea la mejor opción para cargar archivos sin importar el tamaño y la velocidad de internet de los usuarios?.

Muchas gracias de antemano.
Ernesto

Alondra Guadamuz Bermúdez dijo...

Hola Leandro como vas, tengo una consulta sobre la carga de archivo. Antes que nada te tengo que agradecer el postear este articulo que ufff, es de una gran

ayuda para muchos.
Bueno, te comento mi incidente, lo que estoy realizando es la carga de archivos a una tabla de mi BD, el codigo realiza la carga muy bien, pero con archivos

de muy reducido tamaño (tamaños de menos de 1MB); para ello he investigado un poco y me llevo a aumentar algunas configuraciones tanto en el web.config del

servicio como en el web.config del cliente, mira lo que tengo en ambos:

-- web.config servicio








-- web.config cliente















Pero sabes, aun no me permite cargar archivos de grande tamaño. Me puedes ayudar a identificar este inconveniente y el cual me dice que es una Excepcion en

la Comunicacion. De hecho el mensaje de error que me manda es: The remote server returned an error: (400) Bad Request.

Ah, otro detalle que no queria pasar por alto es que la carga permite cualquier tipo de archivos.

Te lo agradezco mucho Leandro.

Leandro Tuttini dijo...

hola Alondra

algo que me llamo la atencion es porque mencionas dos web.config en la explciacion

se supone que la pagina donde realzias el upload de la imagen es una sola, y no hay un cliente que actualziar porque el cliente seria el browser del usuario y eso no se configura
solo el server con el iis que aloja el sitio es quien se define los valores de tamaño permitido en la subida, que ademas si es menos de 1Mb no deberias tener problemas con la configuracion por defecto que permite archivos de hasta 4Mb

o es que el sitio web se comunica con un web service ? porque ojo la forma en que pasas info a un servicio puede ser distinta a usar el fileupload

saludos

Alondra Guadamuz Bermúdez dijo...

Hola Leandro, segun he estado analizando el caso, sera que en la capa de transporte la comunicacion este algo muy por debajo para permitir la carga de archivos de mas de 1mb? Tenes alguna solucion para dicha modificacion o algun comentario que me ayude.

Gracias y totales gracias

Leandro Tuttini dijo...

hola Alondra

no veo porque un archivo de menos de un mega no puedas subirse por medio del fileupload al servidor

si se que hay un limite al tamaño maximo de archivo, que esta definido por defecto en 4Mb, pero el tamaño minimo no hay restriccion

no sera un problema en la logica del codigo que generas? o sea cuando subes el archivo no llega el array del byte al servicor? y realizas el SaveAs de este a un archivo

saludos

LeinerB dijo...

Buenas tardes Leandro,

Primero quiero agradecer por este gran aporte, me ha sido muy útil pero no he podido llegar a lo que quiero.

Mi caso es el siguiente he hecho una galeria de imagenes en JQuery y quiero generar las imagenes dinamicamente. Las imagenes las traigo de la BD y vienen en Bytes[].

Estoy trabajando asp.net con C#

En el load del formulario uso un ciclo for de acuerdo a la cantidad de imagenes en la BD. Dentro de este for uso una clase .ashx para generar la url de la imagen (string url="GetImage.ashx") que la muestro mediante this.UnDiv.InnerHTML

El problema es que me muestra en la galeria solo la ultima imagen de todas las que estan en la BD. Haciendo un paso a paso logro evidenciar que el recorrido del for se hace de manera correcta, pero solo esta yendo una vez a la clase .ashx

Por favor si puedes ayudarme te agradecería. Saludos

LeinerB dijo...

Bueno ya he solucionado mi problema y era en la forma con la que obtenía el valor de un parámetro en la clase .ashx

Lo hacia mediante una variable global creada en el Web.confing. ahora recibo el parámetro enviándola por post string url = "GetImage.ashx?id=Valor" y en mi clase lo obtengo de esta manera doc = context.Request.Params["doc"].ToString();

Gracias de todos modos :D Saludos

Leandro Tuttini dijo...

hola LeinerB

si usas jquery, porque estas usando
this.UnDiv.InnerHTML

porque no lo haces con jquery, usando el selector
$('#iddiv').html(aqui html);

puedes insertar codigo html

saludos

Alondra Guadamuz Bermúdez dijo...

Hola Leandro, te adjunto la parte del codigo donde realizo la carga, no le veo nada extraño si.

Muchas gracias de antemano.

public void Guardar()
{
foreach (UploadedFile file in RadAsyncUpload1.UploadedFiles)
{
byte[] bytes = new byte[file.ContentLength];
file.InputStream.Read(bytes, 0, file.ContentLength);
DocumentoSoporteSContractClient connection = new DocumentoSoporteSContractClient("basicEndPoint");
try
{
DocumentoSoporteInsertarRQ command = new DocumentoSoporteInsertarRQ();
command.DocSoporteInRQ = new DocumentoSoporteDContract(); //datacontract

command.DocSoporteInRQ.TipoDeDocumento = file.GetName();
command.DocSoporteInRQ.Documento = new Binary { Bytes = bytes };
command.DocSoporteInRQ.CreadoPor = (Page as SIFPage).SecurityInfo.SIFUser.SIFUserId; ;
command.DocSoporteInRQ.FechaCreacion = System.DateTime.Now;

connection.DocumentoSoporteInsertar(command.DocSoporteInRQ); //se manda a guardar
Mensaje.Show("carga satisfactoria")
}
catch
{
thrown;
}
}
}

Leandro Tuttini dijo...

hola Alondra

la verdad desconozco algunas funcionalidades de ese codigo

- nunca use un RadAsyncUpload1, imagino es un control de telerik para subir archivos multiples, quiero pensar que eso funciona

- pero lo que si nunca usea es DocumentoSoporteSContractClient
imagino por el nombre que es algo de sharepoint, pero la verdad no tengo idea de como se usa

saludos

lucia rosas dijo...

Hola yo estoy haciendo un sitio web en el cual en la pagina elijo una imagen para subirla entonces el nombre de la imagen lo guardo en un hidden field.
Y entonces al guardar en la BD quiero que se muestre la ruta.
Bueno mi problema es que el fileupload va vacio en la propiedad FileName.

Leandro Tuttini dijo...

hola lucia rosas

el tema es que al poner la ruta en un hidden no estas haciendo un upload de la imagen solo defines una ruta de una imagen que esta en el cliente, pero nunca haces el upload en si solo llevas un string con el nombre del archivo y solo eso

debes dejar seleccionado el archivo en el fileupload para que se pueda realizar la subida del byte[] al sitio web, usar un hidden no funciona

saludos

walter linares dijo...

hola leandro felicitarte por un excelente articulo y super entendible, algo puntual cuando creaba el handler me salia un error aqui;
public class HttpImageHandler:IHttpHandler
Indicandome que el miembro isrehusable no estaba creado para lo cual el vs me lo solucion agregando esto:
#region Miembros de IHttpHandler

public bool IsReusable
{
get { return false; }
}

#endregion
lo cual en el return determinaba una excepcion lo cula quite y expuse tu conocimiento de return false y vacan dio de maravillas, por si acaso alguno tenia dicho problema, un saludo cordial leandro y esperamos muchos articulos igual, adios.

Jhonny Rondón dijo...

Bueno yo le hice de esta forma.. espero que alguien le sirva.. en la forma como lo hice le borro el nombre a la foto y le agrego un código asi limito el tamaño de letra que pueda tener la foto.. solo tomo la extensión de la imagen ante de subirla..

string oFotos = "";
string sExt = "";
string oError = "";

try
{

Random r = new Random();
int numeros = r.Next(10000000, 99999999);

oFotos = Path.GetFileName(imgSubida.PostedFile.FileName);
sExt = Path.GetExtension(oFotos);
oFotos = oFotos.Substring(oFotos.LastIndexOf(".") + 1).ToLower();
oFotos = DateTime.Now.ToString("yyyyMMdd_hhmmss") + "_" + numeros + sExt;
if (oFotos.Equals(""))
{
oError += "Selecciones una imagen
";

}
else if (!ValidaExtension(sExt))
{
oError += "Solo es permitido imagenes con las extensiones jpg, png
";


}
else if (imgSubida.HasFile)
{

imgSubida.PostedFile.SaveAs(Server.MapPath("~/imagenes") + "\\" + oFotos);


}



}
catch
{
oError += "Selecciones una imagenes con las extensiones jpg, png
";
}
if (oError != "")
{

lblError.Text = oError;
}else
{
aca ingresa a la base de datos.
}


private bool ValidaExtension(string sExt)
{
Boolean rel = false;
switch (sExt)
{
case ".jpg":
case ".jpeg":
case ".png":
case ".gif":
case ".bmp":
rel = true;
break;
default:
rel = false;
break;

}
return rel;
}

Johanna Miranda dijo...

Hola Leandro, podrias ayudarme con algo, quisiera listar los archivos en una sola celda, al dar clic sobre el archivo que debe estar separado por los demas, se debe permitir descargar, gracias espero su respuesta

Leandro Tuttini dijo...

hola Johanna

no entendi, como es eso de una sola celda? o sea si usas un gridview se supone que tienes una fila y columna para cargar los datos

o estas pensando en usar otro tipo de control? y no el gridview, como se usa en el articulo

saludos

Johanna Miranda dijo...

Mira, tengo una tabla formada por 4 campos: fecha, usuario, descripcion, archivos.
Los usuarios si tienen algún requerimiento, describen su requerimiento y pueden adjuntar mas de un archivo.
Yo guardo los archivos adjuntos en una ruta del servidor, la cosa es que al poner todos los datos en el gridview como consulta, desearia se vieran los nombres de los archivos que ha adjuntado cada cliente,osea, esto deberia verse en la columna archivos, al dar clic en el nombre del archivo se descargue..

:( . Hice algo con hyperlink pero los nombres del los archivos se ven como que si todos fueran un solo link.. Y yo deseo que cada nombre se vea como link

Leandro Tuttini dijo...

hola Johanna

has validado como defines el link dentro del ItemTemplate del gridview ?

porque por lo que comentas parece ser un problema con el template
aunque no me queda claro que es lo que aparece como un link, porque si defines el hiperlink en una columna del grid solo deberias aplicarse a esa columna

saludos

alex joao dijo...

Hola leandro, Estoy trabajando con tu articulo de este blogg sobre el UploadFile,, esotoy trabajandor en Visual Studio 2010 ,, pero tengo unn problema,, Cuando elijo el archivo que quiero subir , al momento de querer cargarlo primero valida si el file upload tiene un archivo cargado asi:
if (FileUpload1.HasFile)
{
string fullPath = Path.Combine(Server.MapPath("~/files"), FileUpload1.FileName);
FileUpload1.SaveAs(fullPath);
}
}
pero el FileUpload1.HasFile siempre me da falso ,, apesar de que ya elegi la imagen que quiero subir y no se por que,ya comprobe y en efecto no aperece informacion del archivo ,, plis help me¡¡¡¡

Leandro Tuttini dijo...

hola alex

la verdad no sabria decirte que podra esta pasando

de casualidad usas el UpdatePanel ? porque se que hay problemas con el fileupload cuando estas con este integrado


saludos

alex joao dijo...

Si leandro que crees? ya solucione el problemita,, y si es por el UpdatePanel ,, mi solucion fue Integrar el AsyncFileUploadExtender ,, muchas gracias ... muy buen tutorial

nelson mateo dijo...

buenas
saludos espero tu ayuda soy nuevo en esto. estoy elaborando un proyecto en visual webdeveloper
tengo una base de datos creada que llame imagen para guardar las imagenes del proyecto y recionarlas con los usuarios.
el problema estas cuando intento gurdar las la imagen en la base de datos,segui el articulo pero me da errol,no si creaste una cadena de conexion en el web.config o algo asi,si la creaste me puedes enviar los datos de como las crearte y sus parametros, yo cree una pero las imagen no se guardan en la base de datos,si en la carpeta fotos de mi proyecto,te envio el codigo que uso para la cadena de conexion







este es metodo que utilisas para guardar la imagen podificado

public static void GuardarImagen(string nombrearchivo, int length, byte[] imagen)
{
using (SqlConnection conn = newSqlConnection(ConfigurationManager.ConnectionStrings["conn"].ToString()))
{
conn.Open();
string query = @"INSERT INTO Imagene (, imagen)
VALUES @imagen)";

SqlCommand cmd = new SqlCommand(query, conn);
SqlParameter imageParam = cmd.Parameters.Add("@imagen", System.Data.SqlDbType.Image);
imageParam.Value = imagen;
cmd.ExecuteNonQuery();
}

}

con este codigo cargo la imagen a las carpeta foto de mi proyecto

protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
try
{
FileUpload1.SaveAs(Server.MapPath("~/fotos" + FileUpload1.FileName));
Label1.Text = "File name: " +
FileUpload1.PostedFile.FileName + "
" +
FileUpload1.PostedFile.ContentLength + " kb
" +
"Content type:" +
FileUpload1.PostedFile.ContentType;
}
catch (Exception ex)
{
Label1.Text = "ERROR: "+ ex.Message.ToString();
}
else
{
Label1.Text = "You have not specified a file or the file has not been found.";
}
}

esto otro que pones en tu articulo para cuardar la imagen
protected void btnGuardar_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
using (BinaryReader reader = new BinaryReader(FileUpload1.PostedFile.InputStream))
{
byte[] image = reader.ReadBytes(FileUpload1.PostedFile.ContentLength);

ImagenesDAL.GuardarImagen(FileUpload1.FileName, FileUpload1.PostedFile.ContentLength , image);

}
}



espero me puedas ayudar, gracias de todas formas

Leandro Tuttini dijo...

hola nelson

dices que tienes un error y no guarda la imagen, pero cual seria ese error, siemrpe ayuda conocer el mensaje del problema

ademas el connection string esta definido en el web.config podrias tomarlo de alli

o sino guiarte por
http://www.connectionstrings.com/sql-server-2008

saludos

Hector Medina dijo...

Hola amigo!! tienes la descarga de imagenes una ala ves!!! que tal si quiero descargar varias a la ves, sera posible esto?

agradeceria tu ayuda

Unknown dijo...

Hola Leandro que tal, he revisado tu post y me ha parecido muy bueno.
Ahora quisiera saber
como obtener la imagen guardada en la BD como Byte[], convertirla de nuevo a imagen y colocarla tal vez en un control Image de mi Pagina web.

Hector Medina dijo...

Unknown para mostrar una imagen en un control image se necesita..

1-crear una pagina donde vamos a descargar la imagen de la base de datos del campo blob, y esta variable la vamos a recibir como un array de bites.... esta debe ser una nueva pagina ejemplo mostrarimagen.aspx... para hacer mas dinamica la cosa vamos a pasarle el id de la imagen a mosrrar por el metodo get
mostrarimagen.aspx?id=25

2-una ves teniendo la imagen debemos escribir esta en pantalla con response

3-en el control donde queramos mostrar la imagen en la propiead imageurl le debemos asignar la direccion url de la pagina creada

un ejemplo...

se crea una nueva pagina mostrarimagen.aspx.......

en el evento load recuperamos la imagen de la base de datos eso no lo explicare....

para recibir parametros get es de la siguiente manera

Request.QueryString("id")
''esto servira para poder usar esta pagina para mostrar cualquier imagen

''una ves echo la consulta en la base de datos recuperamos la iumagen

Dim imagen() As Byte = 'imagen'
Response.ContentType = "image/jpeg"
''esto depende de que tipo de imagen sea Response.BinaryWrite(imagen)

eso es todo lo que se necesita....


ahora en la pagina donde este el control image le asignamos en la priopiedad imageurl="mostrarimagen.aspx?id=20"

y listo eso es todo

Leandro Tuttini dijo...

hola Hector

el tema es que el link apunta a un solo archivo o imagen a la vez, si quieres descargar varios habria que ver de poner algun checkbox o seleccion y algun boton que tomes esa seleccion y arme algun zip para enviarlo por el Request

o sea la respuesta solo puede ser una sola, la uncia forma es agrupando los archivos seleccionados en un zip

saludos

Leandro Tuttini dijo...

hola Unknown

pero me pregunto has analizado el articulo?
porque es muy raro que realices esta pregunta si lo hiciste

poner un byte[] en un control image de la pagina no se puede, requieres que algo lo ponga en el Response, es por eso que se hace uso de un handler para esa tarea

el control imagen de la pagina se asocia a ese handler para que muestre la imagen, peor esto esta mencionado en el articulo

saludos

Hector Medina dijo...

Leandro pero como se podria hacer esto?? e encontrado informacion pero cuando los archivos estan directamente en el servidor y no en la base de datos!!

alguna idea??? te agradeceria tu ayuda!!

Leandro Tuttini dijo...

hola Hector

la tecnica es la misma solo cambia el lugar donde recuperas la informacion, si los archivo estan en la db en lugar de usar la clase File de .net usarias una query a la db para recuperar el array de byte que forma el archivo

en este mismo articulo aplcia esa tecnica, quizas debas usar el File.WriteAllBytes() para crear un archivo fisico que comprimir, aunque si puede encontrar la vuelta para comprimir desde un Stream se peude pasar el byte[] a stream para enviarlo al zip sin archivo intermedio

saludos

Hector Medina dijo...

Hola Leandro

muy bueno lo que me recomendaste, use File.WriteAllBytes() para guardar las imagenes en el servidor!! no sabia que se podia!!!

y despues comprimi la carpeta donde estaban con DotNetZipLib y luego la mande a descargar!!!

Mucha grascias por tu ayuda!!!

José Augusto De la Rosa Paulino dijo...

Hola Leandro por favor necesito de tu ayuda lo que pasa es que estoy empezando en lo que es la programacion y estoy creando un proyecto persona para manejar profesores de un colegio y necesito agregarle la foto al cada profesor que registre en el sistema y no le encuentro camino para hacerlo estoy utilizando Linq, VB.Net en ASP.net

por favor agradeceria mucho de tu acostumbrada ayuda.-

Gracias de antemano.-

Leandro Tuttini dijo...

hola Jose

no analizaste el articulo

[ASP.NET] GridView – Edición Empleados

alli implemento lo que creo quieres lograr

saludos

AlfredMeza dijo...

Hola Leandro

Antes que nada agradecerte ya que es muy util toda la informacion que compartes.

Podrias dar una revisada a este thread por favor, estoy un poco atorado en ello, es respecto a guardar una imagen en base de datos.
Para ello tendria que subir la imagen al servidor?
Es la unica causa que se me ocurre para que no funcione, ya que en el ambiente local no hubo problema alguno

Gracias por tu tiempo

http://social.msdn.microsoft.com/Forums/es-ES/aspnetmvces/thread/c0ef5b6c-a6c4-4038-9cc4-c94ce8f4b112

Leandro Tuttini dijo...

hola AlfredMeza

respondi en el foro

saludos

AlfredMeza dijo...

Muchas gracias Leandro, podrías echarle otro vistazo por favor, a lo mejor es algo muy noob que estoy obviando o no sé te agradecería mucho si puedieras ver.

http://social.msdn.microsoft.com/Forums/es-ES/aspnetmvces/thread/c0ef5b6c-a6c4-4038-9cc4-c94ce8f4b112

Gracias

Abel Quispe Orellana dijo...

Hola Leandro, Excelente tutorial.

Una pregunta:

¿como podría hacer para que esos datos ingresados me lo muestre al principio?.Es posible eso!!

Espero me ayudes. Gracias

Leandro Tuttini dijo...

hola Abel

a que datos ingresados haces referencia? a la imagen

ademas al principio de quien? cuando se carga la pagina, o cuando seleccionas una imagen

saludos

Abel Quispe Orellana dijo...

hola!! Me refiero a un registro nuevo, cuando se inserta uno. "te lo muestra al final" , mi pregunta es si ese dato nuevo se muestre al principio, mejor dicho como si fuera el primer dato ingresado.

Cuando se carga la pagina de ListarEmpleado

Leandro Tuttini dijo...

hola Abel

si el registro lo agregas a una base de datos podrias ordenarlo de forma descendente

SELECT * FROM Tabla ORDER BY campo DESC

pero si lo agregas a un datatable (que imagino conservas en la Session) podrias utilizar el metodo Insert() para indicar el index donde quieres agregarlo


saludos

Abel Quispe Orellana dijo...

Gracias Leandro!! Por el aporte, Me fue de ayuda el de la base de datos Muy Agradecido...

jonathan gonzalez dijo...

Cordial saludo leandro estuve probando tu código y ps en un proyecto q cree nuevo no me esta mostrando la imagen aparece una "x"
ya he revisado y no puedo hallar con el error

Leandro Tuttini dijo...

hola jonathan

la X quiere decir que no pudo recuperar la imagen

estas implementando un handler para recuperar la imagen? si es asi al poner un breakpoint puedes validar que ingresa, o sea resuelve el handler

recuerda que debes configurar este en el web.config para que funcione

saludos

jonathan gonzalez dijo...

Gracias leandro si era configurar el halder en web.config

MarianoNct dijo...

Hola Leandro, excelente tu post! una consulta yo necesitaría mostrar una imagen en pantalla y que con un boton o algo me pase a la siguiente. Eso seria posible?

MarianoNct dijo...

Leandro lo que quiero decir es, si existe alguna posibilidad de agregar un control DataPager al Gridview y que me las muestre de a un por ejemplo. Se puede realizar eso?

Leandro Tuttini dijo...

hola MarianoNct

no creo que el GridView tenga esta funcionalidad, quizas se pueda simular si paginas de a un item

pero podrias ver de utilizar un

DetailsView (Control de servidor Web)

con este control podrias mostrar de un item, y si lo paginas con paginas de 1, podrias pasar de un registro a otro

saludos

MarianoNct dijo...

En un DetailsView puedo mostrar las imagenes desde la base de datos tal como tu lo hiciste en el ejemplo con el GridView?

Leandro Tuttini dijo...

hola MarianoNct

el control DetailsView es muy similar al GridView ya que en este se puede definir un template, solo que esta pensando para mostrar de a un item

en este pondrias un control Image cuya url la definas mediante el Eval() para asignar el id en el querystring del handler que nos devolvera la image, digo si es que la imagen esta en la tabla de tu db

saludos

MarianoNct dijo...

Excelente informacion Leandro! Muchísimas gracias por tu ayuda.
Saludos

Edu dijo...

Muy bueno el aporte. Es la primera vez que hago algo así.
Quisiera saber en donde va el siguiente código, porque no logro que me lo reconozca.
public static void GuardarImagen(string nombrearchivo, int length, byte[] imagen)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
{
conn.Open();

string query = @"INSERT INTO Imagenes (nombre, length, imagen)
VALUES (@name, @length, @imagen)";

SqlCommand cmd = new SqlCommand(query, conn);

cmd.Parameters.AddWithValue("@name", nombrearchivo);
cmd.Parameters.AddWithValue("@length", length);

SqlParameter imageParam = cmd.Parameters.Add("@imagen", System.Data.SqlDbType.Image);
imageParam.Value = imagen;

cmd.ExecuteNonQuery();

}

}

Desde ya muchas gracias.

Leandro Tuttini dijo...

hola Edu

imagino deberia ir en la accion del boton que confirma la operacion que crea la entidad en donde subirias la imagen al sitio

ese codigo podrias usarlo como lo realizo en el articulo

saludos

raulale79 dijo...

Que tal Leandro , muchas gracis por publicar el articulo es de gran utilidad, a mi me funciono bien, pero tengo un detalle cuando muestro la imagen en mi navgador ie version 10 con win8 funciona muy bien, pero cundo lo quiero ver en otra pc con windows xp y navegador ie version 8 marca una crusita en lugar de desplegar la imagen. Cabe clarar que funciona bien en win 2008, 2003, win 7 y 8, pero en xp no, sabes que se pueda deber?.

Leandro Tuttini dijo...

hola raulale79

si en IE8 luego de cargada la pagina presionas F12 para abrir la developer tool, he inspeccionas la imagen, que url puedes visualizar ?

es una url valida, si la llevas al IE10 resuleve la imagen, puedes verla

es raro que en un browser funcione y en otro no, has probado en FireFox o Chrome?

saludos

Raul dijo...

Hola que tal Leandro, gracias por contestar, fijate que cuando inspecciono el elemento y copio la url de la imagen y la copio y pego en un nuevo explorer este despliega una ventana que me dice si quiero abrir o no el archivo, lo que me da a entender es que si tiene acceso a la carpeta y al archivo fisico. cuando le doy abrir como que se cicla ya que abre un nuevo explorer y me vuelve a hacer la pregunta de como desdeo abrir el archivo, asi n veces. No he podido instalar otro navegador ya que es una maquina que esta en produccion y no puedo hacer instalaciones de otra indole. Este caso si esta muy raro, no se si pueda ser el ie o el codigo, pero si fuera el codigo no funcionara en las demas pc's.

Leandro Tuttini dijo...

hola Raul

como es la url que copias ? es del estilo http://sitio/carpeta/imagen.jpg

porque si es del estio c:\...
entonces es incorrecto, eso no es una url sino el acceso a una carpeta fisica

no es necesario que instales nada en el servidor, se supone que tienes que acceder al sitio dewde otra pc conectada la red, alli si puedes instalar otro browser si lo necesitas

saludos

Raul dijo...

Hola que tal Leandro ya pude resolver el problema, simplemente cambie el codigo en el Generic Handler, cabe aclarara que el codigo lo tome de otro foro. Mira este es el codigo que tenia en el ProcessRequest del Handler.ashx:

context.Response.ContentType = "Image/gif"; context.Response.WriteFile(ImageId); context.Response.End();


por este otro:

string path = ImageId;
Image img = Image.FromFile(path);
img.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
context.Response.ContentType = "image/gif";
context.Response.End();


El cambio simplemente se baso en tomar una imagen fisica que esta en un servidor compartido, convertira en arreglo de bits y ese arreglo de vits pintarlos como imagen, con eso basto para que funcionara.

no entiendo el porque de la icompatibilidad ya que si funcionaba en los demas windows pero en windows xp no.

Pero aqi dejo esta expereicna por si a alguien mas se tepa con esto.

Mucha sgracias por tu ayuda Leandro.

MarianoNct dijo...

Hola Leandro, te postie pero creo que no salio por si se repite el msj.

Quería preguntarte si sabes como hacer lo siguiente... Presionar un boton, y que se guarde una imagen predeterminada en la BD sin utilizar un File Update, es decir solo se ve el boton en la pantalla. El problema es que nose como guardar la imagen en una variable... la imagen esta en el C y se llama Prueba1.jpeg.. tenes idea de como puedo resolver este tema?

Muchas Gracias por tus aportes.
Mariano

Leandro Tuttini dijo...

hola MarianoNct

la imaen en si es un array de byte, por lo que si usas el

File.ReadAllBytes()

podrias recuperarla a una avariable para posteriormente asignarla al parametro que la lleva al campo de la tabla

saludos

Willians Rodriguez dijo...

buen día sr. leandro, excelente articulo, una consulta utilice la parte para descargar la imagen una vez guardada, pero en ie y firefox descarga los archivos sin la extension del mismo, probe con safari, opera y chrome y trabaja perfectamente. alguna idea de por que y como solucionar el inconveniente?

Leandro Tuttini dijo...

hola Willians

validaste que el nombre del archivo tenga extension cuando defines

Response.AddHeader()

quizas si alli no defines la extension al descargar llegue sin esta al browser

saludos

Willians Rodriguez dijo...

Buenas Tardes, Tiene usted razón, solo le pasaba el titulo, concatene el titulo y la extensión,

la extensión la estaba guardando como content-type (ejemplo: application/pdf).

y se resolvio el error en el IE, sigue en firefox me parece que es por que el titulo tiene espacios en blanco, voy a probar quitandolos.

Naty dijo...

Hola podrias ayudarme como cargar una fotografia con fileupload a una Image para guardar en sql desde C# estoy aprendiendo a utilizar C#.net, quiero guardar en una tablña docentes que contine nombre, ci, ciudad, email y fotografia.

Leandro Tuttini dijo...

hola Naty

pero este articulo justamente explica como lograr lo que estas planteando

pudiste analiza el codigo del articulo? hay algun punto que no se entienda?

saludos

Naty dijo...

de hecho si lo he leido pero me indica como cargar la imagen en un datagrid pero yo necesito cargar la imagen en un image estoy trabajando en visual estudio.net

Leandro Tuttini dijo...

hola Naty

no importa donde la necesites cargar la tecnica es la misma

defines un handler que es quien pondra la imagen en el Response recuperando los byte[] del campo de la db que contiene el archivo

esa url es la que asignar el ImageUrl del control

esto si es que la imagen como archivo, o sea byte[] esta en la tabla, si solo tienes el nombre del archivo de la imagen eso es diferente

saludos

Iván Astello dijo...

Leandro, si a todo esto que explicas en tu articulo, me gustaría añadirle una funcionalidad, tener una carpeta en mi computadora (P. ejemplo: C:\Archivos) y quisiera que al momento de yo poner un documento digamos de office, o una imagen o un pdf dentro de esa carpeta, el grid en donde se muestran los archivos se actualice, como sincronizando mi carpeta en el escritorio con el grid y desde luego poder desde el grid descargar y visualizar el archivo, que me aconsejas?



Leandro Tuttini dijo...

hola Iván

usando solo asp.net lo que planteas no se puede lograr

ahora si puede desarrollar alguna aplicacion residente como ser un Windows Service y usar el

FileSystemWatcher

podrias monitorear la carpeta y ante la presencia del archivo que se lance la accion que subiria este quizas por FTP, HTTP o algun otro protocolo al servidor

pero necesitas de algo ejecutando local en la pc para poder detectar y subir el archivo

saludos

chrcito dijo...

Estimado Leandro tengo un inconveniente las extenciones (GIF o JPG ...) del archivo no están guardadas en la base datos , creo que por eso solo me muestra algunas imágenes, como podría solucionar esto.

chrcito dijo...

LEandro verifique y carga las imagenes correctamente en Iexplorer más no en chrome por que puede ser?

Leandro Tuttini dijo...

hola chrcito

recuerdo que una vez me paso algo similar y se debio al formato de la imagen

prueba recuperar el archivo de la imagen, abrelo con el ms paint y grabalo como una imagen nueva, prueba validar si esa imagen como archivo puedes verla en Chrome

a veces sucede que el formato con que fue generada la imagen no se visualiza, solo es cuestion de editar y volver a grabar la imagen

saludos

lukaz dijo...

Ing. gracias por sus excelentes aportes. Mi pregunta es con un contro HTML Editor de Ajax Control Kit, quiero guardar el contenido de una tesis en una base de datos. Es posible hacerlo ? o cual seria la mejor forma de realizar esta tarea

Carmen Esperanza dijo...

hola..no puedo ver el codigo de los botones, descargue el proyecto eb vb. el proyecto hecho en c# si puedo ver el codigo que tienen los botones pero en el de vb no.

Leandro Tuttini dijo...

hola lukaz

pero que control usas? seria algo como este

http://htmleditor.codeplex.com/

si es un control ajax deberias poder accederlo desde el codigo de la pagina en el servidor y tomar su contenido para insertarlo en la db
pero no sabria decirte que evento o propiedad usar porque no se que control usas o en que accion vas a realizar el registro

saludos

Leandro Tuttini dijo...

hola Carmen

descargue el codigo del articulo en vb.net y fui al archivo SubirImagen.aspx.vb alli pude ver el codigo de los botones sin problema

no vayas al diseñador de la pagina ve directo al codigo asociado para ver los eventos de los botones

saludos

Carmen Esperanza dijo...

SubirImagen.aspx.vb
este archivo no lo muestra nose pero no aparece, solo las clases he podido ver pero nada mas de codigo.

Leandro Tuttini dijo...

hola Carmen

no puedes visualizarlo en el solution explorer, pero si accedes con el explorador de windows a la carpeta donde esta el proyecto puedes verlo?

si accedes al codigo de aspx, que muestra el VS?

estas programando en c# o vb.net ?

saludos

chrcito dijo...

Las imágenes no se muestran cuando lo subo al servidor, es decir cuando hago la prueba localmente carga perfectamente pero al subir la aplicación web al servidor no se muestran las imágenes. esta es la página para que puedas ver:
www.creativa.com.pe

también abrí un nuevo tema en el foro pero parece que quedo en olvido por favor ayúdame.

http://social.msdn.microsoft.com/Forums/es-ES/1260a75c-83e9-4cac-8d1a-1ebe41827441/no-se-muestran-imgenes-de-gridview-usando-un-handler?forum=netfxwebes#502bc293-1465-46be-b05b-c9baa960136b

Leandro Tuttini dijo...

hola chrcito

respondi en el foro

saludos

chrcito dijo...

Leandro te respondí también en el foro no me dejes de lado por favor.

chrcito dijo...

Leandro me apoyas en el foro porfas ya t envie la imagen.

http://social.msdn.microsoft.com/Forums/es-ES/1260a75c-83e9-4cac-8d1a-1ebe41827441/no-se-muestran-imgenes-de-gridview-usando-un-handler?forum=netfxwebes#502bc293-1465-46be-b05b-c9baa960136b

chrcito dijo...

Leandro por fas ayúdame en el foro hasta ahora no le encuentro solución.

http://social.msdn.microsoft.com/Forums/es-ES/1260a75c-83e9-4cac-8d1a-1ebe41827441/no-se-muestran-imgenes-de-gridview-usando-un-handler?forum=netfxwebes#4df361fa-858e-45fa-815b-1d8ad82fbd41

Leandro Tuttini dijo...

hola chrcito

respondi en el foro

saludos

JorgeD dijo...

Estimado Leandro: He leido su articulo y me ha resultado de ayuda para algunos conocimientos, pero quisiera saber como se guarda un archivo (de cualquier tipo) en una base de access en el tipo de datos "Datos Adjuntos", mediante una instruccion SQL con vb2010.
Desde ya muy amable de su parte.

Jorge

Leandro Tuttini dijo...

hola Jorge

para esto esta el otro articulo

[ASP.NET] Grabar Archivo en base de datos

saludos

chrcito dijo...

Leandro nuevamente yo solicitando tu ayuda en el foro
http://social.msdn.microsoft.com/Forums/es-ES/1260a75c-83e9-4cac-8d1a-1ebe41827441/no-se-muestran-imgenes-de-gridview-usando-un-handler?forum=netfxwebes#4df361fa-858e-45fa-815b-1d8ad82fbd41

Leandro Tuttini dijo...

hola chrcito

respondi en el foro

saludos

Esthela Mtz dijo...

Hola Leandro me parece muy bueno tu articulo, soy nueva en .net yo solo necesito descargar un archivo, pero sin cargarlo así, no se si me explico, lo que quiero es que el contenido de la carpeta files se vea en esa tabla pero sin que yo lo cargue así, no quiero usar base de datos sino descargarlos desde una carpeta que tendré en mi servidor solo que no tengo muy claro como hacerlo.

frelee Barrientos dijo...

Hola Leandro.

Realmente tengo problemas con un gridview porque necesito mostrar diferentes archivos por ejemplo pdf, word, excel y winrar los cuales vienen de base de datos, para que el usuario pueda diferenciarlo los tipos de archivos para lo cual necesito mostrar cada archivo con con su logo respetivo, los logos no lo tengo en base de datos sino afuera. Gracias, espero que me pueda ayudar.
Un saludo cordial

JorgeD dijo...

Hola Leandro: Tendras algún articulo para bajar/leer un archivo guardado como imagen de bits en una tabla de access mediante vb 2010 o superior.
Gracias de antemano.

Leandro Tuttini dijo...

hola JorgeD

la tecnica con Access es la misma que explico en este articulo
solo que ne lugar de usar SqlConnection usarias OleDbConnection, en lugar de SqlCommand usarias OleDbCommand
peor el resto es igual, recuperas del campo un byte[] que seria la imagen

saludos

AmriEdardna dijo...

Hola Leandro,

una duda: como puedo hacer para comprimir la imagen captada por el Fileupload antes de convertirla a un array de bytes? suponiendo que estoy trabajando en webform y no puedo (debo) usar rutas locales