2012-09-16 88 views
3

如何在ASP.NET C#網頁中使用FileUploader控件檢查上載文件的文件類型?檢查上傳文件的類型

  1. 我試圖檢查的文件擴展名,但是當JPEG圖像(例如Leonardo.jpg)被重命名爲有一個PDF的擴展名(例如Leonardo.pdf)它顯然失敗。

  2. 我試圖

    FileUpload1.PostedFile.ContentType.ToLower().Equals("application/pdf") 
    

    但上面的代碼表現爲第一做了同樣的方式失敗。

是否有任何其他方式來檢查實際的文件類型,而不僅僅是擴展名?我看了一下ASP.NET how to check type of the file type irrespective of extension

編輯:我嘗試下面的代碼在計算器的職位之一。但是這沒有用。對此有任何想法。

/// <summary> 
/// This class allows access to the internal MimeMapping-Class in System.Web 
/// </summary> 
class MimeMappingWrapper 
{ 
    static MethodInfo getMimeMappingMethod; 

    static MimeMappingWrapper() { 
    // dirty trick - Assembly.LoadWIthPartialName has been deprecated 
    Assembly ass = Assembly.LoadWithPartialName("System.Web"); 
    Type t = ass.GetType("System.Web.MimeMapping"); 

    getMimeMappingMethod t.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)); 
} 

/// <summary> 
/// Returns a MIME type depending on the passed files extension 
/// </summary> 
/// <param name="fileName">File to get a MIME type for</param> 
/// <returns>MIME type according to the files extension</returns> 
public static string GetMimeMapping(string fileName) { 
    return (string)getMimeMappingMethod.Invoke(null, new[] { fileName }); 
} 
} 

回答

4

不要使用文件擴展名解決MIME類型,而是使用「Winista」進行二進制分析。

說別人用jpg擴展名重命名爲exe。您仍然可以確定真實的文件格式。它不會檢測到swf或flv,但幾乎可以處理其他衆所周知的格式,並且可以使用十六進制編輯器添加更多可檢測的文件。

下載Winista:here

凡Winista未能檢測到真正的文件格式,我已經使出回URLMON方法:

public class urlmonMimeDetect 
{ 
    [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)] 
    private extern static System.UInt32 FindMimeFromData(
     System.UInt32 pBC, 
     [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl, 
     [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer, 
     System.UInt32 cbSize, 
     [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed, 
     System.UInt32 dwMimeFlags, 
     out System.UInt32 ppwzMimeOut, 
     System.UInt32 dwReserverd 
    ); 

public string GetMimeFromFile(string filename) 
{ 
    if (!File.Exists(filename)) 
     throw new FileNotFoundException(filename + " not found"); 

    byte[] buffer = new byte[256]; 
    using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) 
    { 
     if (fs.Length >= 256) 
      fs.Read(buffer, 0, 256); 
     else 
      fs.Read(buffer, 0, (int)fs.Length); 
    } 
    try 
    { 
     System.UInt32 mimetype; 
     FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0); 
     System.IntPtr mimeTypePtr = new IntPtr(mimetype); 
     string mime = Marshal.PtrToStringUni(mimeTypePtr); 
     Marshal.FreeCoTaskMem(mimeTypePtr); 
     return mime; 
    } 
    catch (Exception e) 
    { 
     return "unknown/unknown"; 
    } 
} 
} 

從Winista方法裏面,我依傍URLMON這裏:

public MimeType GetMimeTypeFromFile(string filePath) 
    { 
     sbyte[] fileData = null; 
     using (FileStream srcFile = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 
     { 
      byte[] data = new byte[srcFile.Length]; 
      srcFile.Read(data, 0, (Int32)srcFile.Length); 
      fileData = Winista.Mime.SupportUtil.ToSByteArray(data); 
     } 

     MimeType oMimeType = GetMimeType(fileData); 
     if (oMimeType != null) return oMimeType; 

     //We haven't found the file using Magic (eg a text/plain file) 
     //so instead use URLMon to try and get the files format 
     Winista.MimeDetect.URLMONMimeDetect.urlmonMimeDetect urlmonMimeDetect = new Winista.MimeDetect.URLMONMimeDetect.urlmonMimeDetect(); 
     string urlmonMimeType = urlmonMimeDetect.GetMimeFromFile(filePath); 
     if (!string.IsNullOrEmpty(urlmonMimeType)) 
     { 
      foreach (MimeType mimeType in types) 
      { 
       if (mimeType.Name == urlmonMimeType) 
       { 
        return mimeType; 
       } 
      } 
     } 

     return oMimeType; 
    } 

更新:

摸出用魔法在這裏更多的文件是一個FILE SIGNATURES TABLE

+0

謝謝。這是工作。 – crazyTechie

+0

我在哪裏可以得到這段代碼的解釋 – crazyTechie

+0

它是一箇舊的Java項目的.Net端口,我找不到它的信息,不確定它是否仍然存在。 –

0

檢查名稱或擴展名絕不是一個可靠的想法。您可以確定的唯一方法是您實際上閱讀文件的內容。

即如果你想檢查文件的圖像,你應該嘗試從文件加載圖像,如果失敗,你可以確定它不是一個圖像文件。這可以使用GDI對象輕鬆完成。

對於PDF文件也是如此。

結論是,不要依賴用戶提供的名稱或擴展名。

+1

加載文件可能是一個問題,如果加載整個文件並等待崩潰或異常因爲這正是黑客工作的方式,他們會產生一個「格式錯誤的文件」並將其上傳,目的是使接收器中斷,如果文件構建正確,可能會產生緩衝區溢出/溢出,從而導致服務器(通過強制錯誤)運行放在文件中的實際代碼,我不認爲這是「正常」,我只是說這是黑客工作的方式之一,所以我只加載一小部分文件並檢查標題信息重刑第一。 – BerggreenDK

0

你可以檢查你FileApload通過

ValidationExpression =「^文件類型。+。(([pP] [dD] [fF])|([jJ] [pP] [gG])|([pP] [nN] [gG])))$「

對於Rar文件類型等,請添加([rR] [aA] [rR]) ...