检查上传文件的类型

如何在ASP.NET C#网页中检查使用FileUploader控件上载的文件的文件类型?

  1. 我尝试检查文件扩展名,但是当JPEG图像(例如Leonardo.jpg )重命名为具有PDF扩展名(例如Leonardo.pdf )时,它显然会失败。

  2. 我试过了

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

    但这失败了,因为上面的代码与第一个代码的行为方式相同。

有没有其他方法来检查实际的文件类型,而不仅仅是扩展名?

我看了ASP.NET如何检查文件类型的类型而不管扩展名 。

编辑:我尝试从stackoverflow中的一个post下面的代码。 但这不起作用。 对此有任何想法。

 ///  /// This class allows access to the internal MimeMapping-Class in System.Web ///  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)); } ///  /// Returns a MIME type depending on the passed files extension ///  /// File to get a MIME type for /// MIME type according to the files extension public static string GetMimeMapping(string fileName) { return (string)getMimeMappingMethod.Invoke(null, new[] { fileName }); } } 

不要使用File Extensions来计算MIME类型,而是使用“Winista”进行二进制分析。

假设有人用jpg扩展名重命名exe 您仍然可以确定真实的文件格式。 它不检测swf或flv,但几乎所有其他众所周知的格式,你可以得到一个hex编辑器来添加它可以检测到的更多文件。

下载Winista: 在这里 。

在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; } 

更新:

使用魔法来计算更多文件是一个文件签名表

检查名称或扩展名绝不是一个可靠的想法。 您可以确定的唯一方法是您实际读取文件的内容。

即如果要检查文件中的图像,则应尝试从文件中加载图像,如果失败,则可以确定它不是图像文件。 这可以使用GDI对象轻松完成。

PDF文件也是如此。

结论是,不要依赖用户提供的名称或扩展名。

您可以在FileApload中检查您的文件类型

ValidationExpression = “^ +(([PP] [日] [FF])|([JJ] [PP] [gG的])|([PP] [NN] [gG的]))。。)$”

例如:您可以为Rar文件类型等添加([rR] [aA] [rR])