I know this has been asked before, but neither of the solutions worked for me. I want to know if the file uploaded to my server (via a .ashx) is of type .xlsx, .xls or .csv.
I tried using the magic numbers listed here, but if I for example change the extension of a .msi to .xls, the file will be recognized as .xls... The following code ilustrates what i said:
private bool IsValidFileType(HttpPostedFile file)
{
using (var memoryStream = new MemoryStream())
{
file.InputStream.CopyTo(memoryStream);
byte[] buffer = memoryStream.ToArray();
//Check exe and dll
if (buffer[0] == 0x4D && buffer[1] == 0x5A)
{
return false;
}
//Check xlsx
if (buffer.Length >= 3 &&
buffer[0] == 0x50 && buffer[1] == 0x4B &&
buffer[2] == 0x03 && buffer[3] == 0x04 ||
buffer[0] == 0x50 && buffer[1] == 0x4B &&
buffer[2] == 0x05 && buffer[3] == 0x06)
{
return true;
}
//Check xls
if (buffer.Length >= 7 &&
buffer[0] == 0xD0 && buffer[1] == 0xCF &&
buffer[2] == 0x11 && buffer[3] == 0xE0 &&
buffer[4] == 0xA1 && buffer[5] == 0xB1 &&
buffer[6] == 0x1A && buffer[7] == 0xE1)
{
return true;
}
return false;
}
}
Then I tried using urlmon.dll
, something like the following, but it still recognizes the file as .xls
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
static extern int FindMimeFromData(
IntPtr pBC,
[MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)] byte[] pBuffer,
int cbSize,
[MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
int dwMimeFlags,
out IntPtr ppwzMimeOut,
int dwReserved);
public static string GetMimeFromFile(string file)
{
if (!File.Exists(file))
throw new FileNotFoundException(file + " not found");
int MaxContent = (int)new FileInfo(file).Length;
if (MaxContent > 4096) MaxContent = 4096;
FileStream fs = File.OpenRead(file);
byte[] buf = new byte[MaxContent];
fs.Read(buf, 0, MaxContent);
fs.Close();
int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out IntPtr mimeout, 0);
if (result != 0)
throw Marshal.GetExceptionForHR(result);
string mime = Marshal.PtrToStringUni(mimeout);
Marshal.FreeCoTaskMem(mimeout);
return mime;
}
I was thinking that maybe I should try to open the uploaded file with some library for example ExcelDataReader but I'm not sure if this is the best approach.
Any help would be appreciated.
How about open file Excel by EPPlus
of Interop
and catch an exception if it isn't an excel file
FileInfo fileInfo = new FileInfo(filePath);
ExcelPackage package = null;
try
{
package = new ExcelPackage(fileInfo);
}
catch(Exception exception)
{
}
Or there is a 3rd party (not tested) which verify the type of file.
FileInfo file = new FileInfo("C:\Hello.pdf");
if ( file.isExcel())
Console.WriteLine("File is PDF");