En el anterior artículo sobre este tema, hace unos días, contaba los rudimentos de cómo se suben archivos a un servidor Web mediante HTTP usando sólo ASP.NET, inclyendo también un código de ejemplo sencillo que lo hacía. Entonces prometí que iba a comentar algunas pegas de esta implementación.

Se trata de problemas que normalmente no se comentan en los libros ni en la documentación directamente y que pueden volver loco a más de uno si se los encuentra durante un desarrollo. Los que voy a comentar en el post de hoy tienen que ver con la subida al servidor de archivos grandes.

- Limitación de seguridad por defecto

Una cosa que no se suele contarse es que la subida de archivos al servidor en ASP.NET está limitada por defecto a 4 MB. Si intentamos usar el código de ejemplo del artículo anterior para subir un archivo de más de 4 MB veremos que se produce un error. Se trata de una limitación de seguridad que trae ASP.NET que impide peticiones al servidor mayores de este tamaño (un envío de archivo no es más que una petición POST que envía como datos el contenido del propio archivo).

Para superar esta limitación es necesario tocar el archivo web.config de configuración de la aplicación ASP.NET. En concreto es necesario otorgar un valor al atributo maxRequestLength del nodo , así:

<HTTPRUNTIME maxrequestlength="12288" />

En este caso se establece el limite en archivos de 12 MB (12 x 1024) de tamaño.

- Consumo de memoria

Cuando ASP.NET acepta un archivo lo que hace es almacenarlo en memoria mientras no decidimos que hacer con él. esto es un problema grave con archivos grandes ya que la memoria consumida no se corresponde con el tamaño del archivo, sino que es sensiblemente mayor debido al modo en que se envía y se almacena (unas 5 veces mayor). Por eso si dejamos subir archivos muy grandes y tenemo sun sitio con mucho tráfico podemos tener problemas. Por ejemplo si tenemos cinco usuarios subiendo a la vez un archivo de 10 MB estaremos ocupando con estos procesos ¡alrededor de 250MB de memoria RAM!. ¡Ahí es nada!.

Ante esto poco se puede hacer lamentablemente salvo tal vez buscar algún tipo de componente de terceras partes que evite este problema. La verdad es que no les hubiera costado nada a los chicos de Microsoft hacerlo mejor y almacenar los archivos en una carpeta temporal de disco ¿verdad?.

- Errores de tiempo máximo superado

Las páginas ASP y ASP.NET tienen establecido un tiempo máximo para ejecutarse (por defecto 90 segundos) que, si se supera, se considera que la página está fuera de control (se ha "colgado") y se genera un error interrumpiendo su ejecución. Esto se hace para evitar que una página mal programada pueda consumir excesivos recursos del servidor incidiendo en el desempeño de las demás.

Nuevamente esto sólo es un problema con archivos grandes, claro.

Se trata de una cuestión complicada de resolver ya que nunca tienes ni idea de cuánto va a tardar en subir un determinado archivo. Dependerá del tamaño de dicho archivo y de la velocidad de las lñineas tanto del servidor (para aceptarlo) como del cliente (para enviarlo). Lo único que se puede hacer es asignar un valor suficientemente alto a la propiedad ScriptTimeout del objeto Server y rezar para que de tiempo a subir el archivo. No tengas miedo de asignar un valor alto a esta propiedad ya que sólo afecta a la página actualmente en ejecución y no a las demás. Sólo hay que tener en cuenta que el valor máximo aceptable es un día, es decir, 86.400 segundos.

- No se puede indicar el progreso de la subida

Se trata de otro problema debido a las limitaciones del componente que viene con ASP.NET. Hasta que acaba el proceso de subida de archivos no se obtiene información alguna de cómo va el proceso. es decir, es un "todo o nada", por lo que no se puede mostrar de ningún modo información sobre el proceso al usuario que sube el archivo.

La solución (parcial) en este caso, aparte de usar componentes de otra gente (claro), pasaría por enviar al principio de la página, antes de cualqueir otro procesamiento, el HTML necesario para que en el lado cliente se muestre un GIF animado con una barra de progreso ficticia o alguna otra animación.  Por lo menos de este modo no se le da la sensación al usuario de que no pasa nada y se evita su impaciencia.

Con todos estos problemas no pretendo hacer desistir anadie del uso del componente que viene con ASP.NET. nada más lejos de mi intención. Es gratuito, fácil de usar y en la mayor parte de los casos funciona sin problemas. Lo que quiero es que tengáis claro que no es lo más adecuado para utilizar en caso de trabajar con archivos muy grandes. Espero haberlo conseguido.

Escrito por un humano, no por una IA