Subiendo archivos asíncrono en asp.net con el control “AsyncFileUpload”

Recientemente se liberó una nueva versión del famoso “Ajax Control Toolkit”, adicional a los arreglos y estabilidad que exhibe el release, este incluye dos nuevos controles: SEADRAGON y ASYNCFILEUPLOAD de este ultimo dedicaré este post.

Para nadie es un secreto que uno de los dolores de cabeza de los desarrolladores que usan ASP.NET AJAX, específicamente los “UpdatePanels” es la limitación de poder incluir dentro de este, un control de “FileUpload” para la carga de archivos. En los buscadores y foros te daras cuenta que un gran numero de desarrolladores ha tenido que hacer implementaciones complejas, comprar control o desistir de hacer una carga de archivo asíncronas dentro del update panel. Para este problema los chicos del AJAX Control Toolkit desarrollaron el control “AsyncFileUpload” que es un control bien sencillo de implementar y además mantiene la características de los ya conocidos controles del toolkit.

Basicamente el control se define así:

<toolkit:AsyncFileUpload ID="AsyncFileUpload1" runat="server" 
OnClientUploadError="uploadError"
OnClientUploadComplete="uploadComplete"
UploaderStyle="Modern"
ThrobberID="Throbber" UploadingBackColor="#CCFFFF"
CompleteBackColor="Aqua" />

Este control está compuesto por los siguientes:

Eventos

  • UploadedComplete: evento que ocurre en el servidor cuando la cargar del archivo ha sido satisfactorio.
  • UploadedFileError: evento que ocurre en el servidor cuando la carga del archivo ha generado algún error.

 

Propiedades

  • CompleteBackColor: El color de fondo del control cuando la carga ha sido completada.
  • ContentType: Se obtiene el tipo de contenido (MIME Content Type) del archivo cargado.
  • ErrorBackColor: el color de fondo del control cuando la carga ha genrado un error.
  • Filename: se obtiene el nombre del archivo.
  • Hasfile: un boleano que indica si el control tiene archivo o no.
  • OnClientUploadError: el nombre de la funcion de Javascript que se ejecutará si falla la carga.
  • OnClientUploadComplete: el nombre de la funcion de Javascript que se ejecutará cuando se complete la carga.
  • PostedFile: se obtiene un objeto HttpPostedFile con acceso al archivo cargado.
  • ThrobberID: (debió ser ProgressImage) Es el ID del control que mostrará el progreso.
  • UploaderStyle: define la apariencia del control (Tradicional o Moderno).
  • UploadingBackColor: color de fondo del control cuando está cargando el archivo.
  • Width: define el largo del control.

 

Metodos

  • SaveAS(archivo as string): Guarda el archivo pasandole como parametro la ruta y el nombre del archivo.

 

En la implementación que anexo en este post el HTML se observa de esta forma:

<form id="form1" runat="server">
<
asp:ScriptManager ID="sm" runat="server" />
<
h1>
Carga de archivo asíncrona</h1>
<
div id="demoTitle">
Demostración Control "AsyncFileUpload"
</div>
<
div id="uploadArea">
<
toolkit:AsyncFileUpload ID="AsyncFU"
runat="server"
OnClientUploadError="uploadError"
OnClientUploadComplete="uploadComplete"
UploaderStyle="Modern"
ThrobberID="Throbber"
UploadingBackColor="#CCFFFF"
CompleteBackColor="AliceBlue" />
<
div id="Throbber" runat="server"
style="display: none;">
<
img align="middle" alt="" src="indicator.gif" />
</
div>
</
div>
<
br />
<
br />
<
div>
<
strong>Ultimo evento del lado del servidor:</strong></div>
<
div id="msgServerSide" runat="server">
</
div>
<
br />
<
br />
<
div>
<
strong>Eventos del lado del cliente:</strong></div>
<
div id="msgClientSide" runat="server" style="display: none">
</
div>
</
form>

 

Estas funciones de javascript le permiten al control crear comportamientos y funcionalidades directamente en el cliente:

<script type="text/javascript">
function
uploadError(sender, args) {
var divmsg = $get("<%= msgClientSide.ClientID %>");
divmsg.className = "error";
divmsg.style.display = 'block';
divmsg.innerHTML = 'File: ' + args.get_fileName() +
'<br/>' + 'Error: '
+ args.get_errorMessage();

}
function uploadComplete(sender, args) {
var divmsg = $get("<%= msgClientSide.ClientID %>");
divmsg.className = "success";
divmsg.style.display = 'block';
divmsg.innerHTML = 'File: ' + args.get_fileName() + '<br/>'
+ 'Length: ' + args.get_length() + 'bytes';
}

</script>

Del lado del cliente manejamos los eventos inyectando scripts a través del scriptmanager.

Protected Sub AsyncFU_UploadedComplete(ByVal sender As Object, _
ByVal e As AjaxControlToolkit.AsyncFileUploadEventArgs) _
Handles AsyncFU.UploadedComplete

Dim myScript = "top.$get('" & msgServerSide.ClientID & _
"').innerHTML = 'Estatus: Satisfactorio <br/> Archivo: " & e.filename & _
"<br/> Tamaño: " & AsyncFU.FileBytes.Length.ToString() & "';"
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), "size", myScript, True)

'AsyncFU.SaveAs("AQUI VA LA RUTA PARA GRABAR EL ARCHIVO")

End Sub

Protected Sub
AsyncFU_UploadedFileError(ByVal sender As Object, _
ByVal e As AjaxControlToolkit.AsyncFileUploadEventArgs) _
Handles AsyncFU.UploadedFileError

Dim myScript = "top.$get('" & msgServerSide.ClientID & _
"').innerHTML = 'Error: " & e.statusMessage & "';"
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), "error", myScript, True)

End Sub

 

Desde aquí puedes descargar el proyecto que utiliza el control.

 

Conclusiones

Pros:

  • Permite usar el control dentro de un Updatepanel.
  • Se pueden manejar funcionalidades del lado del cliente.
  • Soluciona en gran parte el problema de cargar de archivo asíncrono en asp.net.
  • Si ocurre un error la ruta del archivo seleccionado persiste en el control.
  • Permite tener acceso a diferente estado cuando se carga el archivo.

Contra:

  • No tiene la capacidad para múltiples archivo.
  • Por alguna razón cuando seleccionas el archivo la carga se hace automática.