views:

2796

answers:

4

My WPF application gets a file from the user with Microsoft.Win32.OpenFileDialog()...

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

And my ASP.NET MVC application serves it up for download at a web site with 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

But FileStreamResult() needs a content type string. How do I know the correct content type of my file?

+1  A: 

It looks like you still have the filename when you go to set the content type. You could pick the correct mime type for the file extension, or default to something like "application/base64".

Assuming the person downloading it will be using a web browser, try to stick to the common ones: MIME Types Known By IE

rally25rs
+4  A: 

I've replaced the FileExtension column in my database table with a ContentType column.

I populate it when I upload a file.

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

I determine the content type with this function:

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

This works, but it seems inelegant.

Zack Peterson
+6  A: 

how about this: http://www.aspcode.net/Getting-mimetype-Windows.aspx

This would be the best solution IMO
Sky Sanders
+2  A: 

I use a custom config section in web.config (I leave the task for writing the custom configuration section to you):

<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>

I use Path.GetExtension() and map that to one of the types listed in Extensions.

Will