检查上传文件的类型
如何在ASP.NET C#网页中检查使用FileUploader
控件上载的文件的文件类型?
-
我尝试检查文件扩展名,但是当JPEG图像(例如
Leonardo.jpg
)重命名为具有PDF扩展名(例如Leonardo.pdf
)时,它显然会失败。 -
我试过了
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]) …