sábado, 26 de junio de 2010

ASP.NET - Subir y descargar archivos del servidor mediante pagina aspx intermedia

download_file Lo prometido es deuda (lean los comentarios de este otro post), así que vamos con el desarrollo del post.
En esta ocasión vamos a realizar el proceso de:
1.- Guardar, en una carpeta del servidor, archivos, los cuales deben guardarse con otros nombres (nombres autogenerados, por ejemplo: 3F2504E0-4F89-11D3-9A0C-0305E82C3301).

2.- Guardar en la base de datos, el nombre original del archivo y el nuevo nombre.

3.- Recuperar los nombres y rutas de los archivos subidos al servidor y listarlos en un gridview.

4.- Basado en los puntos 2 y 3, permitir descargar los archivos con su original nombre.

Para completar este ciclo voy a crear en la base de datos una tabla llamada document_attachment y los respectivos procedimientos almacenados para la gestión de archivos.
Entonces, este es el script T-SQL que uso para el caso ( una tabla y 3 procedimientos almacenados):
CREATE TABLE [dbo].[document_attachment](
[attachmentid] [int] IDENTITY(1,1) NOT NULL,
[filename] [varchar](250),
[fileguid] [varchar](50),
CONSTRAINT [pk_document_attachment] PRIMARY KEY CLUSTERED 
([attachmentid] ASC)
)
GO
--------------------------------------------------
CREATE PROCEDURE[dbo].[document_attachment_GetAll]
AS

SELECT
[attachmentid],
[filename],
[fileguid]
FROM [dbo].[document_attachment]

GO
--------------------------------------------------
CREATE PROCEDURE[dbo].[document_attachment_Insert]
@attachmentid int output,
@filename varchar(250),
@fileguid varchar(50)

AS
INSERT INTO[dbo].[document_attachment](
[filename],
[fileguid]
)
VALUES(
@filename,
@fileguid
)
SET @attachmentid = SCOPE_IDENTITY()
GO

--------------------------------------------------
CREATE PROCEDURE[dbo].[document_attachment_GetByGuid]
@guid varchar(50)
AS

SELECT
[filename],
[fileguid]
FROM [dbo].[document_attachment]
WHERE [fileguid] = @guid
--------------------------------------------------
Antes de pasar al código ASP.NET, les recomiendo que guarden la cadena de conexión a la base de datos en el web config (para el ejemplo está sin encriptar, …pero uds deben encriptarlo)

<connectionStrings>
<add name="DB" connectionString="server=.\SQLEXPRESS;database=my_database;uid=sa;pwd=xxxxxxxxxxxxxxx" />
</connectionStrings>

Otra cosa, deben crear una carpeta llamada Uploads (en la raiz de su aplicación), que es donde se guardarán los archivos que se suben… a esta carpeta hay que darle permisos de lectura/escritura al usuario SERVICIO DE RED.
uploads_folder

Ahora sí, necesitamos dos páginas aspx:
1.- Uploader.aspx, que es la página que permite subir los archivos al servidor e, inmediatamente después actualiza el contenido del gridview con los archivos subidos.

2.- Downloader.aspx, que es la página intermedia para descargar archivos… gracias a esta página podemos evitar que el usuario sepa desde qué carpeta se descargan los archivos y además en el código de esta página pueden hacer las verificaciones que quieran antes de permitirle al usuario descargar el archivo. Tú me preguntarás: puedo usar un archivo ashx (que es más ligero) en lugar de una pagina aspx para descargar? la respuesta es sí.

Este es el código completo:
Uploader.aspx
uploader

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="width: 350px; background-color: #f2ceea; padding: 10px; margin: 20px">
Seleccione archivo:<asp:FileUpload ID="FileUpload1" runat="server" />
<hr />
<asp:Button ID="btnUpload" runat="server" Text="Guardar archivo" />
</div>
<asp:GridView ID="griddocument_attachment" BackColor="lightgreen" Width="400px" runat="server"
AutoGenerateColumns="False" DataKeyNames="fileguid" HeaderStyle-HorizontalAlign="Left"
HeaderStyle-VerticalAlign="Top" RowStyle-VerticalAlign="Top">
<Columns>
<asp:TemplateField HeaderStyle-Width="3%">
<ItemTemplate>
<asp:Image ID="Image1" ImageUrl="~/images/file.png" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Archivo">
<ItemTemplate>
<%# Eval("filename")%>
                </ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Descargar" HeaderStyle-Width="5%">
<ItemTemplate>
<asp:HyperLink ID="hplAttachment" Text='<%# Eval("filename")%>' NavigateUrl='<%# String.Format("~/Downloader.aspx?guid={0}", Eval("fileguid")) %>'
ImageUrl="~/images/download.png" runat="server"></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>    
</form>
</body>
</html>

En el gridview, el hyperlink con la imagen download.png es quien tiene el enlace de descarga, parecido a esto:
http://localhost/Test_UI/Downloader.aspx?guid=ee4a00fa-cfa9-490e-a65c-12d652fd2c00

código VB.NET:
Imports System.Data
Imports System.Data.SqlClient

Partial Public Class Uploader
Inherits System.Web.UI.Page

Private GlobalDBConnection As String = ConfigurationManager.ConnectionStrings("DB").ConnectionString
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack Then Return

document_attachment_GetAll()

End Sub

Protected Sub btnUpload_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnUpload.Click
If Not FileUpload1.HasFile Then Return

Dim fileguid As String = Guid.NewGuid.ToString
Dim FileName As String = FileUpload1.FileName

Try
FileUpload1.SaveAs(Server.MapPath("./Uploads/") & fileguid)
Catch
'error....
Return
End Try

Dim i As Integer = document_attachment_Insert(FileName, fileguid)
If i = 0 Then
'error....
Else
document_attachment_GetAll()
End If

End Sub

Sub document_attachment_GetAll()
Dim connection As New SqlConnection(GlobalDBConnection)
Dim command As New SqlDataAdapter("document_attachment_GetAll", connection)
command.SelectCommand.CommandType = CommandType.StoredProcedure

Dim dt As New DataTable()
command.Fill(dt)

griddocument_attachment.DataSource = dt
griddocument_attachment.DataBind()

End Sub

Function document_attachment_Insert(ByVal filename As String, ByVal fileguid As String) As Integer
Dim connection As New SqlConnection(GlobalDBConnection)
Dim command As New SqlCommand("document_attachment_Insert", connection)
command.CommandType = CommandType.StoredProcedure

Dim p_attachmentid As New SqlParameter("@attachmentid", SqlDbType.Int)
p_attachmentid.Direction = ParameterDirection.Output
command.Parameters.Add(p_attachmentid)
command.Parameters.AddWithValue("@filename", filename)
command.Parameters.AddWithValue("@fileguid", fileguid)

command.Connection.Open()
Try
command.ExecuteNonQuery().ToString()
Catch
Return 0
Finally
command.Connection.Close()
End Try

If Not IsDBNull(p_attachmentid.Value) Then
Return CInt(p_attachmentid.Value)
Else
Return 0
End If
End Function

End Class

Downloader.aspx
 en el lado aspx tiene absolutamente nada, excepto el tag Page:
<%@ Page Language="vb" …………………………………………………… %>
 código VB.NET:
Imports System.Data
ImportsSystem.Data.SqlClient

Partial Public Class Downloader
Inherits System.Web.UI.Page

Private GlobalDBConnection As String= ConfigurationManager.ConnectionStrings("DB").ConnectionString
Protected SubPage_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim guid As String= Request.QueryString("guid")

If String.IsNullOrEmpty(guid) Then Return

' aquí puedes poner las validaciones que quieras

'............   ....................

Dim dt As DataTable = document_attachment_GetByGuid(guid)
If dt.Rows.Count = 0 Then Return

Dim
OriginalFileName As String= dt.Rows(0)("filename")
 DownloadFile(Server.MapPath("./Uploads/") & guid, OriginalFileName)
End Sub

Public Sub
DownloadFile(ByVal FilePath As String, ByVal OriginalFileName As String)
Dim fs As IO.FileStream = Nothing

'obtenemos el archivo del servidor
fs = IO.File.Open(FilePath, IO.FileMode.Open, IO.FileAccess.Read)
Dim byteBuffer(CInt(fs.Length - 1)) As Byte
fs.Read(byteBuffer, 0, CInt(fs.Length))
 fs.Close()

Using ms As New IO.MemoryStream(byteBuffer)
'descargar con su nombre original
Response.AddHeader("Content-Disposition", "attachment; filename=" & OriginalFileName)
 ms.WriteTo(Response.OutputStream)
End Using

End Sub

Function
document_attachment_GetByGuid(ByVal guid As String) As DataTable
Dim connection As New SqlConnection(GlobalDBConnection)
Dim command As New SqlDataAdapter("document_attachment_GetByGuid", connection)
 command.SelectCommand.CommandType = CommandType.StoredProcedure
 command.SelectCommand.Parameters.AddWithValue("@guid", guid)
Dim dt As New DataTable()
 command.Fill(dt)

Return dt
End Function

 End Class


ACTUALIZACIÓN:
Debido a las preguntas que constantemente estoy recibiendo acerca de este post, veo que no ha quedado muy claro... entonces, estoy añadiendo el proyecto completo para que lo descarguen y lo analicen con más calma. 
Debido a que estoy incluyendo la base de datos en la carpeta app_data, lo único que tendrían que modificar en el we.config antes de correr el proyecto es el nombre del servidor de su bd... osea reemplacen .\SS2008 por el nombre del servidor que Uds le hayan puesto.
Es todo, espero que les sea de utilidad.
 ;)

50 comentarios:

albolalo dijo...

Hola Segundo, muy interesante el tema de Subir y descargar archivos del servidor mediante pagina aspx intermedia, de hecho me motivo a probarlo, pero al copiar el codigo y luego al compilarlo en visual studio me aparecieron unos errores, a que se debera??
espero me puedas ayudar.

Segundo Serrano dijo...

Hola albolalo,

quiero aclarar que esta línea:
<%@ Page Language="vb" …………………………………………………… %>

no la debes copiar... sino que cada página ya genera su propio tag Page, que conserve el original nomás...
el resto de líneas sí lo puedes copiar y pegar tal cual.

pero dime cuál es el mensaje de error que está apareciendo?

albolalo dijo...

hola.
este error me da:
Could not find stored procedure 'document_attachment_GetAll'.
en la linea donde esta el command.Fill(dt)
creo que es un problema de conexion con la base de dato

Segundo Serrano dijo...

ya veo,

no es problema de conexión con la base de datos, se conecta correctamente pero no encuentra el procedimiento almacenado.
entonces no has creado el procedimiento almacenado aún...

corre este t-sql en tu base de datos:
---------------------------------------------------
CREATE PROCEDURE[dbo].[document_attachment_GetAll]
AS
SELECT
[attachmentid],
[filename],
[fileguid]
FROM [dbo].[document_attachment]
GO
---------------------------------------------------
si salen otros errores con respecto a tu base de datos, entonces verifica que has creado correctamente la tabla y los 3 procedimientos almacenados... arriba está el script completo.

Saludos

albolalo dijo...

logre solucionar el problema, habia problema con la conexion, asi que funciono de maravilla.
ahora voy a modificarlo un poco para ocuparlo en un sistema de manejo documentos que estoy creando, voy a probar como funciona para ordenar los documentos en distintas carpetas, o quisas agregar un campo mas a la tabla para poder diferenciar los tipos de documentos.
depues te comento como me fue, muchas gracias por la ayuda.
saludos

albolalo dijo...

una consulta, los archivos son almacenados Uploads, pero cual es el formato de estos archivos? porque no estan en el formato en el que los subi.

ahora, crees que sera posible agregar alguna opcion en la cual se puedan editar los archivos y tambien eliminarlos???

Saludos

Segundo Serrano dijo...

pues el formato es el mismo tal cual los subiste, la única diferencia es que se les ha ocultado la extensión...
esto es bueno porque hace que los archivos sólo puedan ser accesados desde la página downloader.aspx, y no repesenta ningún problema porque al momento de ser descargados, reciben su verdadero nombre y extensión.

Con respecto a la opción de editar y eliminar... ok, lo voy a poner, pero será dentro de unos días, por ahora estoy full.

albolalo dijo...

gracias,
tengo una duda, hay alguna diferencia en hacer las consultas de la BD en un procedure que hacerlas desde las paginas aspx. uploader o dowloader.

queria saber si hay alguna posibilidad de plantearte otras consultas sobre un sistema que estoy realizando, en donde voy a utilizar este metodo de almacenamiento de archivo, y de ser asi donde te lo planteo, en este mismo blog o en algun correo?,
gracias de antemano.
saludos

Segundo Serrano dijo...

Hola albolalo,

hay muchas ventajas si usas procedimientos almacenados... te paso un link http://www.forosdelweb.com/f21/ventajas-desventajas-procedimientos-almacenados-web-422991/

Sobre tus preguntas, si ellas aportan a que todos aprendamos... mándalas al blog nomás, si es muy confidencial, mándala al correo.

Saludos,

albolalo dijo...

Segundo, te cuento lo que debo hacer...
estoy haciendo un sistema en asp.net en la cual debo almacenar documentos relacionados a informes o analisis de una empresa, es por esto que me intereso este codigo relacionado a subir y descargar archivos del servidor.
el problema es que debo descargar o subir los archivos segun el area de la empresa en que este.
la empresa consta de plantas las cuales contienen areas y estas a la vez se dividen en secciones, en cada seccion se deben almacenar y descargar documentos.
como hago para saber que cada documento que subo o descargo pertenece a alguna seccion de algun area de una cierta planta.
al igual q la tabla "document_attachment" tengo otras para almacenas las plantas, las areas y secciones, asi como tambien al usuario que sube o descarga un docuemnto.

espero que me puedas ayudar.

saludos cordiales.

Segundo Serrano dijo...

Albolalo,

he añadido una imagen con una explicación, con respecto a lo que me preguntas, al final de este post.

Saludos,

albolalo dijo...

claro, asi es como tengo la base de dato, mi consulta iba mas relacionada a lo que es codigo en asp,net

albolalo dijo...

Hola segundo, te cuento que agregue un textbox a continuacion del boton "examinar" el cual guarda una Observacion del archivo ingresado en la base de datos en la tabla "document_attachment", luego agregue una columna en el Gridview para mostrar la Observacion de cada archivo que fueron guardadas en la BD.
tambien coloque un boton "editar" en cada fila para poder modificar la columna "Observacion", la idea es modificar el contenido de la BD del campo "observacion" desde la Gridview a traves de un Textbox, pero esto lamentablemente no me ha funcionado, es por esto que pido tu ayuda para poder solucionar este problema, vi uno de tus temas relacionado con esto pero no me funciono.
de antemano muchas gracias

joc Cby dijo...

segundo resulta que no me funciona tu codigo, resulta que me sale una entana que dice:

Sys.Webforms.pagerequestmanagerparsererrorexception: the message received from the server could not be parsed. Common

causes for this error are when response is modified by calls to response. write(), response filters, HttpModules, or

server trace is enabled
details: Error parsing near 'HTTP://LOCALHOST/MIN'

estoy haciendo unas pruebas localmente pero no funciona, ayudame es urgente

Segundo Serrano dijo...

Hola,

cuál es la acción que realizas en ese preciso momento? estás usando ASP.NET AJAX?

joc Cby dijo...

resulta que coloque el codigo tuyo en una opcion que existe en un gridview cuando preciono esta opcion aparese el error pero en codigo no se genera un error pero este aparece de todos modos (no se si me hago entender bien) estoy trabajando en una pagina aspx y tengo instalado el ajax (no recuerdo la version pero recuerdo que le decian atlas creo que es la 2 o la 3) si es a lo que te refieres

PD: cuando dige que estaba haciendo unas pruebas localmente me refiero a que estoy ejecutando esta pagina desde el servidor

Segundo Serrano dijo...

joc,
este error realmente no tiene que ver con el código que hice... mas bien es un caso ya conocido y se presenta por conflictos con asp.net ajax u otros casos...
te diría que pruebes mi código en un proyecto aparte (sin ajax) para que descartes el error por ese lado

Por otro lado, te mando un enlace: http://tinyurl.com/25blzu3, dale una chequeada a ver si estás en uno de los casos que mencionan y si encuentras la solución... en caso contrario me avisas para ayudarte.

espero tus comentarios.

joc Cby dijo...

segundo, ya me lo ley y si es el caso porque yo uso un updatepanel de modo que solo se crea un postback parcial de la pagina, en la pagina que me diste hay un link aun blog en el cual esta el link de la solucion el cual es un parche o algo asi por lo que entendi (no se mucho ingles que digamos) el caso es que al final dan un codigo en c# pero no se en que momento se debe usar ese codigo o como lo uso, el link es este: http://siderite.blogspot.com/2008/05/how-to-patch-aspnet-ajax-in-order-to.html

agradesco tu ayuda y pronta respuesta

Segundo Serrano dijo...

joc,

ese código lo pones en tu página y luego llaams el procedimiento desde el page_load...
pero hagamos algo: mándame el código aspx y vb.net de tu página a mi correo sserrano[@]jabs[.]com[.]pe para revisarlo y poder ayudarte.

Saludos.

albolalo dijo...

Hola Segundo, disculpa que te moleste , pero solo queria saber si hay posibilidad de que me puedas ayudar con los problemas que te plantie.

gracias.

joc Cby dijo...

perdona albolalo que me meta pero me parese interesante lo que hiciste, no entiendo bien que es lo que no te funciona, cual es el error que aparese o que pasa

Segundo Serrano dijo...

Hola albolalo,

te envié un correo solicitándote el script de tu tabla para mandarte un ejemplo basado en eso... es posible?

si no es posible me avisas para hacerte un ejemplo que más o menos creo que es lo que quieres.

Saludos,

albolalo dijo...

segundo, te acabo de mandar un correo con el script de la base de datos, muchas gracias

Anónimo dijo...

BUENOS DIAS, TENGO UNA DUDA SOBRE LA FUNCIONALIDAD DE LA APLICACION, SI ME GUARDA EL ARCHIVO EN LA CARPETA UPLOAD, PERO NO ME MUESTRA EL GRIDVIEW, Y REBICE EN EL SQL Y NO INSERTA LA RUTA.

Segundo Serrano dijo...

Hola Marcos,

No guarda la ruta en la tabla de la base de datos para que puedas cambiar de carpeta a tu antojo...

si te fijas en el código de la página Downloader.aspx.vb, allí si incluyo la ruta de los archivos, justo aquí:

Dim OriginalFileName As String= dt.Rows(0)("filename")
DownloadFile(Server.MapPath("./Uploads/") & guid, OriginalFileName)
End Sub

Saludos.

Unknown dijo...

se podra usando lo blob o varbinary en sql server

Segundo Serrano dijo...

Hola Ivan,

claro que se puede....
lo único que tendrías que modificar un poquito, en lugar de recuperar el archivo de la ruta física, tendrías que recuperarlo de la bd... algo así:

Dim byteBuffer() As Byte = dt.rows(0)("mi_archivo_en_bytes_desde_la_bd")

Using ms As New IO.MemoryStream(byteBuffer)
Response.AddHeader("Content-Disposition", "attachment; filename=" & OriginalFileName)
ms.WriteTo(Response.OutputStream)
End Using

Saludos.

Andrea Cortes dijo...

Hola me gusto mucho la información, pero quiero saber si de pronto tienes el código para C

Segundo Serrano dijo...

Hola Andrea,

no tengo el código en csharp, y por ahora no tengo mucho tiempo como para convertirlo a csharp, sorry.

pero te paso un convertidor de codigo VB.NET A c sharp
http://www.developerfusion.com/tools/convert/vb-to-csharp/

Saludos

Kely dijo...

Hola muy buen aporte, pero me gustaria saber lo siguiente es de un aplicativo que estoy haciendo: Si yo tengo un formulario en donde tiene codigo generado, nombre, cargar documento, fecha de inicio y fecha limite. Como podria aplicar el guardar archivos en una carpeta o una base de datos utilizando la implementacion de N capas teniendo dichos objetos. Por que la mayoria solo adjunta y guardar el archivo, pero no lo implenentan para mas datos como se hace ello podria poner en su blogger un aplicativo que indico o en donde puedo ubicar mas informacion de asp.net. Gracias

Segundo Serrano dijo...

Hola Kely,
Lamento no haberte respondido en su momento (he estado muy ocupado)... a ver si entendí: necesitas guardar archivos con más datos (como fecha de inicio, fin).
Lo que puedes hacer es añadirle esos campos a tu tabla, de modo que quedaría sí:
+NombreRealDelArchivo
+NombreGuid
+Descripcion
+FechaInicio
+Fecha Fin
+...

y simplemente se guarda todo al hacer el insert de dicha información en la bd.
Era eso lo que necesitabas?
Saludos

Milton dijo...

Hola Segundo,

Una consulta, como puedo hacer que se muestre una div que bloquee la pantalla mientras se envia la petición de descargar el archivo.?

Ya logre mostrar el div pero no logro ocultarlo ya que al modificar el header el navegador entiende que no debe actualizar la pagina sino que debe mostrar el modal para guardar el archivo.
Yo deseo ocultar el div justo antes de mostrarse el modal.

Saludos,

Felix Campos dijo...

Saludos, Tengo un problemas si estoy en internet explore fabuloso, pero si me paso a FireFox desastre. El archivo se descarga como tipo archivo.

Saludos.....y gracias por tu apoyo.

Unknown dijo...

hola!,recien intente hace tu ejemplo con el control fileupload, resulta q visual no reconoce el control fileupload ni el grid,no se si lo hice correctamente, el codigo en el archivo downloader.aspx solo contiene una linea de codigo, el codigo en vb lo copie talcual en mi archivo downloader.aspx.vb, mi duda es sobre el codigo q va en el archivo uploader.aspx y en el archivo uploader.aspx.vb, ya que creo q ´por ahi esta mi error, en el site.master, hay q modificar algo????? espero me puedas ayudar gracias

Segundo Serrano dijo...

hola maricela,

si pudieras subir tu proyecto a algún lugar y luego enviarme la url para descargarlo y darle una chequeadita, puedes enviarlo a este correo
sserrano[@]neuronasoft[.]net
remueve los corchetes.

creo que sería la forma más rápida de ayudarte.

Saludos

Unknown dijo...

hola, ya te envie el proyecto en visual 2010, espero me puedas ayudar, gracias, o si es q tu lo tienes y me lo pueden enviar, me ayudarias bastante

Segundo Serrano dijo...

maricela,
creo que hay un error... sólo has enviado el archivo .sln

tienes que enviar todo tu proyecto

Saludos

Unknown dijo...

hola, te envie el zip desde hotmal, por q no me dejo desde gmail, espero ahora si lo haya hecho correctamente, gracias

Segundo Serrano dijo...

hola maricela,
no ha llegado ningún correo, porfa intenta enviarlo a este correo sserrano[@]jabs[.]com[.]pe

Unknown dijo...

puedes descargarlo de aqui porfa
https://www.dropbox.com/home?email_just_verified=1#!/home

Segundo Serrano dijo...

maricela,
el enlace que me has enviado sólo me lleva al home...
tienes que enviarme el enlace correcto.

Saludos

Unknown dijo...

https://www.dropbox.com/s/5s1afbges12j3jw/fileupload_c.zip

ups disculpa, que pena.... perdona, haber si ahora si

Segundo Serrano dijo...

Hola a todos,
he incluído un zip con el proyecto completo al final del artículo, para que lo descarguen y hagan la pruebas correspondientes.

Debido a que estoy incluyendo la base de datos en la carpeta app_data, lo único que tendrían que modificar antes de correr el proyecto es el nombre del servidor de su bd... osea reemplacen .\SS2008 por el nombre del servidor que Uds le hayan puesto.

Saludos

Anónimo dijo...

hola, es muy buena la informacion y no se si me puedas ayudar con una cosa.
estoy buscando la manera de descarga un archivo que esta un un ftp, ya tengo el codigo y lo descarga pero la cuestion es que yo en el codigo le tengo que decir en que ubicacion lo descarga y lo que quiero es utilizar de la misma manera que estas colocando para descargar los archivos en esta pagina, osea que se tenga la posibilidad de elegir donde se quiere descargar.

Cordialmente

Francisco Prada

Unknown dijo...

Muy buen aporte amigo mis respetos... :) gracias (Y)

David Bernad "Berni" dijo...

Hola Segundo,

Muchas gracias por tu artículo, es muy útil. Lo he probado y me funciona correctamente.
Pero recientemente me está fallando, me hace todo el proceso pero los archivos que me descarga están corruptos, no puedo abrirlos. ¿Sabes qué puede ser?

Muchas gracias.
Un saludo.

Unknown dijo...

Hola buenas tardes, muchisímas gracias por la ayuda adicional, funciona full...

Erick dijo...

Desde hace unos meses use tu ejemplo para un sistema, ahora estoy tratando de comprimir los archivos y descargar el zip, pero como el nombre se cambia no se como hacerlo, agradeceria tu ayuda, gracias

Unknown dijo...

ALBOLALO me urge contactarme contigo, tengo que hacer algo parecido a lo que mencionas de las carpetas y subir archivos, podrias pasarme tu codigo ??

Unknown dijo...

Estimados amigos, antes agradecerte por el ejemplo, muy bueno, muchas felicidades por el post, comentarte que he realizado todo en C#.NET y me corre todo, pero tengo una duda: cuando descargo los archivos los hace en con el nombre System.Data.DataRow, me pueden ayudar como cambiar esta linea de codigo, ya que a mi parecer es aki donde estoy fallado:
VB: Dim OriginalFileName As String= dt.Rows(0)("filename")
lo que yo hise,
C#: string OriginalFileName = dt.Rows[0].ToString();

Desde ya les agradezco por sus minutos en leer este mensaje.
Saludos desde bolivia.