Si alguna vez te toco trabajar en ambiente web con requerimientos de publicación de archivos, subir archivos desde el cliente o descargarlos, guardar el contenido… cuando enviamos un email con datos adjuntos (aunque esto ultimo se realiza automáticamente) seguramente has trabajado con tipos MIME (Multipurpose Internet Mail Extensions) Y seguramente tienes en tu app o componente un mecanismo para mapear extension a tipo MIME.
Para los que comienzan o necesitan utilizar… Una pregunta relacionada con MIME es ¿Como recuperamos el tipo de un archivo a partir de la extensión o viceversa?
Las opciones:
- Obtener tipo MIME de la Registry (incluso la inversa, la extensión asociada)
- Obtener tipo MIME “manualmente” ayudándonos con una estructura de un Dicccionario (o switch kilométrico)
- Obtener tipo MIME mediante el método GetMimeMapping de la clase System.Web.MimeMapping [Nuevo desde ASP.NET 4.5]
- 3.1 App Pool en Modo Clásico: Obtiene los valores de un diccionario (idem opción 2)
- 3.2 App Pool en Modo Integrado: Obtiene los valores de la lista de tipos Mime configurada en el IIS (y/o app web)
Vemos los pro y contra que tiene cada uno así podemos conocer cuando utilizarlos y cuando “no”.
OPCION 1: Obtener tipo MIME de la Registry de Windows
Si bien esta opción no es recomendada.. Seguramente habrás encontrado algún código que realiza esto. La idea aquí es obtener el tipo MIME o la extensión a partir de la búsqueda dentro del árbol en la Registry
HKEY_CLASSES_ROOTMIMEDatabaseContent Type
A tener en cuenta: El inconveniente de esta opción es que debe estar cargado en el la registry de nuestro sistema operativo donde ese alojara la aplicación web todos los tipos que necesitemos (y allí solo se registran los que las app registran/instalan o viene predeterminado).
- Se debe tener permisos para agregar, así que no es muy factible de escalar en nuestras app web
Como podemos ver, no es muy oportuno utilizarlo, pero dejo la opción para indicar los inconvenientes.
OPCION 2: Obtener el tipo MIME “manualmente” ayudándonos con una estructura de un Diccionario (o switch kilométrico)
La mejor recomendación es utilizar un diccionario para acceder por la key (pero podrías también tener una lista genérica con un tipo de entidad creada para tal fin)
Ejemplo con un Dicccionario:
private static readonly Dictionary<string, string> TiposMime =
new Dictionary<string, string>((IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase)
{
{".323", "text/h323"},
{".3g2", "video/3gpp2"},
{".3gp2", "video/3gpp2"},
{".3gp", "video/3gpp"},
{".3gpp", "video/3gpp"},
{".aac", "audio/aac"},
{".aaf", "application/octet-stream"},
....
A tener en cuenta que necesitaríamos buscar en ella a partir de los dos valores. El mas común siempre es buscar a partir de la extensión pero también nos puede servir en algún momento la inversa buscar a partir de un tipo MIME la extensión correspondiente.
OPCION 3: Obtener mediante el método GetMimeMapping de la clase System.Web.MimeMapping [Nuevo desde ASP.NET 4.5]
Desde la versión de ASP.NET 4.5 tenemos la clase System.Web.MimeMapping que posee un solo método de clase GetMimeMapping que lo bueno es que obtiene los valores MIME de dos lugares diferentes dependiendo del modo que esta configurado el Pool de Aplicaciones en el IIS donde se aloja nuestra aplicación web
- Si se encuentra en modo Clásico: Obtiene el valor de un diccionario que se encuentra entro del assembly (idem a opcion2). Si somos curiosos y vemos el código fuente vemos 343 mapeos (System.Web.dll v4.0.30319.17929)
- Si se encuentra en modo Integrado: Obtiene los valores de la lista de tipos Mime configurada en el IIS. Lo cual es mucho mejor y extensible sin tocar el código de nuestro mapeador
Podemos ver como esta codificado y así investigamos como se obtiene los datos
http://msdn.microsoft.com/en-us/library/system.web.mimemapping.getmimemapping.aspx
Lo bueno
- Al actualizar el sistema operativo más tipos MIME se añaden a IIS
(incluso podríamos agregar los que necesitamos) - Podemos agregar tipos MIME personalizados por app con solo utilizar la seccion system.WebServerstaticContent
(que desde IIS7 toma)
- [Otro post] Agregar tipos MIME personalizados a IIS/IIS Express o nuestra app web en la seccion staticContent del web.config
A tener en cuenta
- El diccionario embebido que se utiliza en modo Classic contiene 343 mapeos (System.Web.dll v4.0.30319.17929)
- El diccionario en modo Integrado (IIS Express): 374 mapeos (archivo ..IISExpressconfig, seccion system.WebServerstaticContent)
… pero además podemos agregar lo que necesitamos para una app específica
Ejemplo
Por ejemplo si necesitamos mapear la extension .yoda al tipo mime starwars/characters
Utilizando el IIS Express (o IIS 7 o superior), podríamos mapear el contenido estatico directamente en el web.config, para que sola esta aplicacion tome este tipo MIME
(mas abajo esta el ejemplo para descargar)
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".yoda" mimeType="starwars/characters" />
</staticContent>
</system.webServer>
</configuration>
Entonces en modo Integrado (nos devolveria) starwars/characters y en modo clasico el tipo MIME por default application/octet-stream
Ejemplo para descargar
Enlace para descargar: http://sdrv.ms/WXeNel