views:

276

answers:

1

My ASP.NET MVC application has pages with attachments and these attachments can be of many different file types.

When the user then wants to access their attachment, I need to fire off an FileResult and return the file attachment which I have the path to.

However, I have no database of mime-types, nor do I know off-hand the mime-type of these files off hand.

What is the proper way to handle this? Is there a way I can return a file and let the framework attempt to figure out the mimetype?

Any suggestions?

+2  A: 

The way I've done it is by keeping a list of well-known extensions and their mime types, and if the extension isn't found then just return it as application/octet-stream. The reason for this is that this mime type is applied to applications (e.g., exe) which the browser, depending on security settings, may allow you to pass to the operating system, thus opening the default editor for that file type. BTW, consider the security implications for every type of file you may accept and transfer to users.

Here's the list I generally use:

  <MimeTypes>
  <MimeType Type="application/mac-binhex40" Extensions=".hqx"/>
  <MimeType Type="application/msword" Extensions=".doc;.docx"/>
  <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;.xlsx"/>
  <MimeType Type="application/vnd.ms-outlook" Extensions=".msg"/>
  <MimeType Type="application/vnd.ms-powerpoint" 
            Extensions=".pot;.pps;.ppt;.pptx"/>
  <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"/>
  <!--Substitute the following two for text/plain if you're sure bad html
  won't get rendered in the browser-->
  <!--<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>

Here's an example of how to use this (c#-like pseudocode).

public string GetMimeType(string ext)
{
  // who would load the file on every method call?  That's just dumb
  var mimes = XElement.Load("MyMimeTypesLolKThx.xml");
  var result = from x in mimes.Elements() 
               where Contains(x, ext) 
               select x.Attribute("Type");
  return result.FirstOrDefault() ?? "application/octet-stream";
}

public bool Contains(XElement el, string ext)
{
  return el.Attribute("Extensions").Value.Contains(ext);  
}
Will
@Will, can you show you piece of code in the controller that traverses this list and pulls the appropriate mime-type? Thanks very much for your answer!
Godel
Sorry, can't. This is all public information (I culled it from wikipedia and other sources) but the code I used to traverse it is not open source. Besides, its 2.0 configuration stuff, which is pretty heavy weight. I'll give you a sample of how to do it, however.
Will