Hola. Estoy implementando un Drag&Drop de Ficheros, para subir imágenes principalmente, pero puede ser cualquier tipo de fichero.He realizado varios cambios para que se reflejen a nivel del cliente, de manera que recojo los ficheros que se alojan en un FormData y luego los envío asíncronamente, a través de un XMLHttpRequest.
Código:
$("#btnUploadFile").click(function () {
var expID = $("#ContentPlaceHolder1_hfExpId").val();
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
alert(files[i].name);
formData.append('file', files[i]);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', "FileHandler.ashx", true);
xhr.setRequestHeader("ExpedienteID", expID);
xhr.onload = function () {
if (xhr.status === 200) {
RefreshFilePanel(); //pendiente de implementar.
} else {
console.log('Something went terribly wrong...');
}
};
xhr.send(formData);
});
Parte en el servidor del Handler (FileHandler.ashx)
Código:
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim documentBytes As Byte()
Dim lExpId As String = context.Request.Headers("ExpedienteID")
If (context.Request.Files.Count > 0) Then
Dim files As HttpFileCollection = context.Request.Files
For i = 0 To files.Count - 1
documentBytes = New Byte(files(i).ContentLength - 1) {}
UploadDocumentBy_ExpID(documentBytes, files(i).FileName, "ASYNC Upload from Exp." & lExpId.ToString, lExpId)
Next
End If
End Sub
Public Shared Sub UploadDocumentBy_ExpID(File As Byte(), FileName As String, FileDesc As String, ExpId As String)
'Dim lConnection As Data.SqlClient.SqlConnection = New Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("cnnMasPer").ToString)
Dim lCommand As Data.SqlClient.SqlCommand = New Data.SqlClient.SqlCommand( _
"INSERT INTO exp_Documentos " _
& "([expId], [Archivo], [Descripcion], [Documento]) " _
& "VALUES (@expId, @Archivo, @Descripcion, @Documento)", GetConnection)
Try
With lCommand
.Parameters.Add("@expId", Data.SqlDbType.Int, 4).Value = ExpId
.Parameters.Add("@Archivo", Data.SqlDbType.NVarChar, 80).Value = FileName
.Parameters.Add("@Descripcion", Data.SqlDbType.NVarChar, 128).Value = FileDesc
.Parameters.Add("@Documento", Data.SqlDbType.VarBinary, File.Length).Value = File
End With
lCommand.ExecuteNonQuery()
lCommand.Parameters.RemoveAt("@expId")
lCommand.Parameters.RemoveAt("@Archivo")
lCommand.Parameters.RemoveAt("@Descripcion")
lCommand.Parameters.RemoveAt("@Documento")
Catch ex As SqlException
Throw New Exception(ex.Message)
End Try
End Sub
Lo que he hecho hasta este punto, ha sido obtener las imágenes, y pasar sus datos binarios en formato byte() para almacenarlos en la BBDD y de momento hasta aquí no hay problema alguno.
El problema viene a posterior, donde intento recuperar esas imágenes desde la BBDD y intento transformar a la inversa, esos datos binarios almacenados en la BBDD de la imagen, a un objeto de tipo Image, pero en la conversión o asignación hay algún tipo de error que no estoy identificando y estoy un poco perdido.
Esta porción de código es esta. Código del .aspx
Código:
<asp:UpdatePanel ID="udpDocument" runat="server">
<ContentTemplate>
<asp:GridView ID="grdDocumentoByExp" runat="server" AutoGenerateColumns="false" Width="250px" DataSourceID="dtsDocumentByExpId">
<Columns>
<asp:BoundField DataField="Archivo" HeaderText="Archivo" />
<asp:BoundField DataField="docId" HeaderText="docId" />
<%--<asp:HyperLinkField DataTextField="Archivo" HeaderText="Open" />--%>
<asp:TemplateField HeaderText="Preview">
<ItemTemplate>
<asp:Image
ID="imgThumb"
runat="server"
ImageUrl='<%# "ImageHandler.ashx?docId=" & Eval("docId")%>'
Width="60px"
Height="60px"
BorderColor="Red"
BorderWidth="2px"
BorderStyle="Solid"
/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Documento" HeaderText="Documento" SortExpression="Doc" Visible="false" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="dtsDocumentByExpId" runat="server"
SelectCommand="SELECT [Archivo], [docId] FROM [exp_Documentos] WHERE ([expId] = @expId) ORDER BY [docId]"
ConnectionString="<%$ ConnectionStrings:cnnMasPer %>">
<SelectParameters>
<asp:ControlParameter ControlID="lblExpId" Name="expId" PropertyName="Text" Type="Int32" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Name="docId" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
</ContentTemplate>
</asp:UpdatePanel>
Código del handler para recuperar las imágenes:
Código:
Public Shared Function GetImageArrayBy_docID(ByVal docID As String) As Byte()
Dim lImage() As Byte
Dim ldap As SqlDataReader
Dim lCommand As Data.SqlClient.SqlCommand = New Data.SqlClient.SqlCommand( _
"SELECT Documento " _
& "FROM exp_Documentos " _
& "WHERE ([docId]=@docId) ", GetConnection)
Try
With lCommand
.Parameters.Add("@docId", Data.SqlDbType.Int, 4).Value = docID
End With
ldap = lCommand.ExecuteReader
ldap.Read()
lImage = ldap.GetValue(0)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
Return DirectCast(ldap(0), [Byte]())
End Function
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim docId As String = context.Request.QueryString("docId")
Dim ms As MemoryStream = New MemoryStream()
Dim fms As MemoryStream = New MemoryStream()
Dim lImgArray() As Byte
If docId <> String.Empty Then
lImgArray = GetImageArrayBy_docID(docId)
ms.Write(lImgArray, 0, lImgArray.Length)
Dim lImg As Image = System.Drawing.Image.FromStream(ms) 'ESTO ME DA ERROR
ms.Dispose()
Dim lOutBmp As Bitmap = New Bitmap(60, 60)
Dim lGrahp As Graphics = Graphics.FromImage(lImg)
With lGrahp
.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
.FillRectangle(Brushes.White, 0, 0, 60, 60)
.DrawImage(lImg, 0, 0, 60, 60)
End With
lOutBmp.Save(fms, System.Drawing.Imaging.ImageFormat.Jpeg)
Dim bmpBytes = fms.GetBuffer
lOutBmp.Dispose()
context.Response.BinaryWrite(bmpBytes)
context.Response.End()
End If
End Sub
me da error a la hora de asignar el byte() de la imagen obtenida de la BD, al intentar asigarla el Stream a la imagen. El error que me indica es que no coinciden los tipos, y por la documentación y la que veo por internet, no está claro, pero como que
la imagen está en tipo raw y por eso no se puede realizar la transformación, pero me he perdido un poco ya en este punto y no se como avanzar. ¿Alguien que me pueda ayudar algo? Gracias de antemano.