2009-03-27 11 views
11

aplicación My WPF recibe un archivo del usuario con Microsoft.Win32.OpenFileDialog() ...¿Cómo determino el tipo de contenido de un archivo en .NET?

Private Sub ButtonUpload_Click(...) 
    Dim FileOpenStream As Stream = Nothing 
    Dim FileBox As New Microsoft.Win32.OpenFileDialog() 
    FileBox.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) 
    FileBox.Filter = "Pictures (*.jpg;*.jpeg;*.gif;*.png)|*.jpg;*.jpeg;*.gif;*.png|" & _ 
        "Documents (*.pdf;*.doc;*.docx;)|*.pdf;*.doc;*.docx;|" & _ 
        "All Files (*.*)|*.*" 
    FileBox.FilterIndex = 1 
    FileBox.Multiselect = False 
    Dim FileSelected As Nullable(Of Boolean) = FileBox.ShowDialog(Me) 
    If FileSelected IsNot Nothing AndAlso FileSelected.Value = True Then 
     Try 
      FileOpenStream = FileBox.OpenFile() 
      If (FileOpenStream IsNot Nothing) Then 
       Dim ByteArray As Byte() 
       Using br As New BinaryReader(FileOpenStream) 
        ByteArray = br.ReadBytes(FileOpenStream.Length) 
       End Using 
       Dim z As New ZackFile 
       z.Id = Guid.NewGuid 
       z.FileData = ByteArray 
       z.FileSize = CInt(ByteArray.Length) 
       z.FileName = FileBox.FileName.Split("\").Last 
       z.DateAdded = Now 
       db.AddToZackFile(z) 
       db.SaveChanges() 
      End If 
     Catch Ex As Exception 
      MessageBox.Show("Cannot read file from disk. " & Ex.Message, "Fail", MessageBoxButton.OK, MessageBoxImage.Error) 
     Finally 
      If (FileOpenStream IsNot Nothing) Then 
       FileOpenStream.Close() 
      End If 
     End Try 
    End If 
End Sub 

Y mi aplicación ASP.NET MVC sirve para arriba para su descarga en un sitio web con FileStreamResult(). ..

Public Class ZackFileController 
    Inherits System.Web.Mvc.Controller 

    Function Display(ByVal id As Guid) As FileStreamResult 
     Dim db As New EfrDotOrgEntities 
     Dim Model As ZackFile = (From z As ZackFile In db.ZackFile _ 
           Where z.Id = id _ 
           Select z).First 
     Dim ByteArray As Byte() = Model.ImageData 
     Dim FileStream As System.IO.MemoryStream = New System.IO.MemoryStream(ByteArray) 
     Dim ContentType As String = ????? 
     Dim f As New FileStreamResult(FileStream, ContentType) 
     f.FileDownloadName = Model.FileName 
     Return f 
    End Function 

End Class 

Pero FileStreamResult() necesita una cadena de tipo de contenido. ¿Cómo sé el tipo de contenido correcto de mi archivo?

+0

¿Cómo se utiliza la función de visualización dentro de la página? – shahkalpesh

+0

No hay página. Esa es una clase de controlador ASP.NET MVC. La pantalla es una de sus Vistas. Pero, como esta vista devuelve FileStreamResult en lugar de ViewResult, no tiene página ASPX. –

Respuesta

15

he reemplazado la columna de la FileExtension en mi tabla de base de datos con una columna ContentType.

Lo lleno cuando cargo un archivo.

Private Sub ButtonUpload_Click(...) 
    ... 
    Dim FileExtension As String = "." + FileBox.FileName.Split(".").Last.ToLower 
    z.ContentType = ContentType(FileExtension) 
    ... 
End Sub 

que determinan el tipo de contenido con esta función:

Function ContentType(ByVal FileExtension As String) As String 
    Dim d As New Dictionary(Of String, String) 
    'Images' 
    d.Add(".bmp", "image/bmp") 
    d.Add(".gif", "image/gif") 
    d.Add(".jpeg", "image/jpeg") 
    d.Add(".jpg", "image/jpeg") 
    d.Add(".png", "image/png") 
    d.Add(".tif", "image/tiff") 
    d.Add(".tiff", "image/tiff") 
    'Documents' 
    d.Add(".doc", "application/msword") 
    d.Add(".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document") 
    d.Add(".pdf", "application/pdf") 
    'Slideshows' 
    d.Add(".ppt", "application/vnd.ms-powerpoint") 
    d.Add(".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation") 
    'Data' 
    d.Add(".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") 
    d.Add(".xls", "application/vnd.ms-excel") 
    d.Add(".csv", "text/csv") 
    d.Add(".xml", "text/xml") 
    d.Add(".txt", "text/plain") 
    'Compressed Folders' 
    d.Add(".zip", "application/zip") 
    'Audio' 
    d.Add(".ogg", "application/ogg") 
    d.Add(".mp3", "audio/mpeg") 
    d.Add(".wma", "audio/x-ms-wma") 
    d.Add(".wav", "audio/x-wav") 
    'Video' 
    d.Add(".wmv", "audio/x-ms-wmv") 
    d.Add(".swf", "application/x-shockwave-flash") 
    d.Add(".avi", "video/avi") 
    d.Add(".mp4", "video/mp4") 
    d.Add(".mpeg", "video/mpeg") 
    d.Add(".mpg", "video/mpeg") 
    d.Add(".qt", "video/quicktime") 
    Return d(FileExtension) 
End Function 

Esto funciona, pero parece poco elegante.

+3

Probablemente debería usar una instrucción switch en lugar de crear un nuevo diccionario cada vez que llame a 'ContentType'. Además, hay un método 'Path.GetExtension' para que no tenga que dividir el nombre de archivo manualmente. – StriplingWarrior

+0

VB.Net 10 es un poco más agradable ... Dim d As New Dictionary (Of String, String) De { {".bmp", "image/bmp"}, {".gif", "image/gif "}, {" .jpeg "," image/jpeg "}} 'etc. – JoelFan

+0

@StriplingWarrior, o mantenga un solo diccionario estático. Si el método se usa con frecuencia y es compatible con gran parte de las extensiones de archivos, creo que se acelerará un poco –

2

Parece que todavía tiene el nombre del archivo cuando va a establecer el tipo de contenido. Puede elegir el tipo de mime correcto para la extensión del archivo, o por defecto a algo como "application/base64".

Suponiendo que la persona que la descarga va a utilizar un navegador web, trate de cumplir con los más comunes: MIME Types Known By IE

+0

+1 para el enlace –

+0

Esto no es lo suficientemente confiable para cualquier cosa que vaya a pasar por la prueba de pluma. Podría cargar un .exe renombrado a .docx usando este ejemplo. –

6

utilizo una sección de configuración personalizada en web.config (dejo la tarea de escribir la sección de configuración personalizada para usted):

<configSections> 
    <section name="mimeTypeMappings" type="MySoftwareLol.MimeTypeMappingSection, MySoftwareLol"/> 
</configSections> 

<mimeTypeMappings> 
    <MimeTypes> 
     <MimeType Type="application/mac-binhex40" Extensions=".hqx"/> 
     <MimeType Type="application/msword" Extensions=".doc"/> 
     <MimeType Type="application/pdf" Extensions=".pdf"/> 
     <MimeType Type="application/postscript" Extensions=".ai;.eps;.ps"/> 
     <MimeType Type="application/rtf" Extensions=".rtf"/> 
     <MimeType Type="application/vnd.ms-excel" Extensions=".xla;.xlc;.xlm;.xls;.xlt;.xlw"/> 
     <MimeType Type="application/vnd.ms-outlook" Extensions=".msg"/> 
     <MimeType Type="application/vnd.ms-powerpoint" Extensions=".pot;.pps;.ppt"/> 
     <MimeType Type="application/vnd.ms-works" Extensions=".wcm;.wdb;.wks;.wps"/> 
     <MimeType Type="application/x-compress" Extensions=".z"/> 
     <MimeType Type="application/x-compressed" Extensions=".tgz"/> 
     <MimeType Type="application/x-gzip" Extensions=".gz"/> 
     <MimeType Type="application/x-msaccess" Extensions=".mdb"/> 
     <MimeType Type="application/x-msmetafile" Extensions=".wmf"/> 
     <MimeType Type="application/x-mspublisher" Extensions=".pub"/> 
     <MimeType Type="application/x-msschedule" Extensions=".scd"/> 
     <MimeType Type="application/x-msterminal" Extensions=".trm"/> 
     <MimeType Type="application/x-mswrite" Extensions=".wri"/> 
     <MimeType Type="application/x-tar" Extensions=".tar"/> 
     <MimeType Type="application/zip" Extensions=".zip"/> 
     <MimeType Type="audio/basic" Extensions=".au;.snd"/> 
     <MimeType Type="audio/mid" Extensions=".mid;.rmi"/> 
     <MimeType Type="audio/mpeg" Extensions=".mp3"/> 
     <MimeType Type="audio/x-aiff" Extensions=".aif;.aifc;.aiff"/> 
     <MimeType Type="audio/x-pn-realaudio" Extensions=".ra;.ram"/> 
     <MimeType Type="audio/x-wav" Extensions=".wav"/> 
     <MimeType Type="image/bmp" Extensions=".bmp"/> 
     <MimeType Type="image/gif" Extensions=".gif"/> 
     <MimeType Type="image/jpeg" Extensions=".jpe;.jpeg;.jpg"/> 
     <MimeType Type="image/pipeg" Extensions=".jfif"/> 
     <MimeType Type="image/tiff" Extensions=".tif;.tiff"/> 
     <!--By default, sends HTML documents as plain text; sending it as text/html may pose security risks--> 
     <!--If you wish to accept the risks, uncomment the following two lines and comment out the third.--> 
     <!--<MimeType Type="text/html" Extensions=".mht;.html;.htm"/>--> 
     <!--<MimeType Type="text/plain" Extensions=".txt"/>--> 
     <MimeType Type="text/plain" Extensions=".txt;.html;.htm"/> 
     <MimeType Type="text/richtext" Extensions=".rtx"/> 
     <MimeType Type="text/tab-separated-values" Extensions=".tsv"/> 
     <MimeType Type="video/mpeg" Extensions=".mp2;.mpa;.mpe;.mpeg;.mpg;.mpv2"/> 
     <MimeType Type="video/quicktime" Extensions=".mov;.qt"/> 
     <MimeType Type="video/x-la-asf" Extensions=".lsf;.lsx;.asf;.asr;.asx;"/> 
     <MimeType Type="video/x-msvideo" Extensions=".avi"/> 
    </MimeTypes> 
    </mimeTypeMappings> 

utilizo Path.GetExtension() y mapa que a una de las tipos listados en Extensiones.

4

Hice una clase de ayuda C# basada en la respuesta de Zacks.

/// <summary> 
/// Helps with Mime Types 
/// </summary> 
public static class MimeTypesHelper 
{ 
    /// <summary> 
    /// Returns the content type based on the given file extension 
    /// </summary> 
    public static string GetContentType(string fileExtension) 
    { 
     var mimeTypes = new Dictionary<String, String> 
      { 
       {".bmp", "image/bmp"}, 
       {".gif", "image/gif"}, 
       {".jpeg", "image/jpeg"}, 
       {".jpg", "image/jpeg"}, 
       {".png", "image/png"}, 
       {".tif", "image/tiff"}, 
       {".tiff", "image/tiff"}, 
       {".doc", "application/msword"}, 
       {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, 
       {".pdf", "application/pdf"}, 
       {".ppt", "application/vnd.ms-powerpoint"}, 
       {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, 
       {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, 
       {".xls", "application/vnd.ms-excel"}, 
       {".csv", "text/csv"}, 
       {".xml", "text/xml"}, 
       {".txt", "text/plain"}, 
       {".zip", "application/zip"}, 
       {".ogg", "application/ogg"}, 
       {".mp3", "audio/mpeg"}, 
       {".wma", "audio/x-ms-wma"}, 
       {".wav", "audio/x-wav"}, 
       {".wmv", "audio/x-ms-wmv"}, 
       {".swf", "application/x-shockwave-flash"}, 
       {".avi", "video/avi"}, 
       {".mp4", "video/mp4"}, 
       {".mpeg", "video/mpeg"}, 
       {".mpg", "video/mpeg"}, 
       {".qt", "video/quicktime"} 
      }; 

     // if the file type is not recognized, return "application/octet-stream" so the browser will simply download it 
     return mimeTypes.ContainsKey(fileExtension) ? mimeTypes[fileExtension] : "application/octet-stream"; 
    } 
} 

Usted podría, por supuesto, quieren mantener el mimeTypes vivo para consultas futuras. Esto es sólo un punto de partida.

3

se puede hacer fácilmente mediante el uso de claves de registro.

Dim regKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("extension") 
If Not regKey Is Nothing Then 
Dim ct As Object = regKey.GetValue("Content Type") 
    If Not ct Is Nothing Then 
    Return ct.ToString() 
    End If 
End If 

¡Esto producirá el mismo resultado que la gran lista mencionada anteriormente!

+1

Esta debería ser la respuesta. –

0

Puede usar la lista This, que contiene 684 extensiones de archivo.

En esta lista, cada par está separado por "~", y cada par tiene el nombre de la extensión y el tipo de contenido separados por "#".

No sé qué idioma estás usando, pero esto está en vb.neta

Cómo se usa:

  1. Añadir un recurso de cadena que le proyecto que contiene la lista. Se parece a esto - enter image description here
  2. Añadir esta clase a su proyecto (que analizar la cadena de diccionario)

    Public Class MIMETypeList 
        Public data As Dictionary(Of String, String) 
        Public Sub New() 
         data = New Dictionary(Of String, String)() 
         Dim Temp() As String 
         For Each TypeConvertion As String In My.Resources.MimeType.Split("~") 
          Temp = TypeConvertion.Split("#") 
          If Not data.ContainsKey(Temp(0)) Then 
           data.Add(Temp(0), Temp(1)) 
          End If 
         Next 
        End Sub 
    End Class 
    
  3. Ahora se puede utilizar de esta manera:

    Dim FileExtension1 As String = ".mp4" 
    Dim FileExtension2 As String = ".html" 
    Dim FileExtension3 As String = ".Random" 
    Dim Converter As New MIMETypeList 
    If Converter.data.ContainsKey(FileExtension1) Then 
        Debug.WriteLine(FileExtension1 & " -> " & Converter.data.Item(FileExtension1)) 
    Else 
        Debug.WriteLine(FileExtension1 & " -> File Content Not Found") 
    End If 
    If Converter.data.ContainsKey(FileExtension2) Then 
        Debug.WriteLine(FileExtension2 & " -> " & Converter.data.Item(FileExtension2)) 
    Else 
        Debug.WriteLine(FileExtension2 & " -> File Content Not Found") 
    End If 
    If Converter.data.ContainsKey(FileExtension3) Then 
        Debug.WriteLine(FileExtension3 & " -> " & Converter.data.Item(FileExtension3)) 
    Else 
        Debug.WriteLine(FileExtension3 & " -> File Content Not Found") 
    End If 
    

    Salida:

    .mp4 -> video/mp4

    .html -> text/html

    .Random -> contenido del archivo no encontrado

Cuestiones relacionadas