我怎样可以通过文件扩展名获取 MIME 类型?
我怎样可以通过文件扩展名获取 MIME 类型?
大部分解决方案都很好用,但为什么要花这么多的精力呢?我们同样可以轻松地获取MIME类型。
在System.Web程序集中,有一个方法可以从文件名获得MIME类型。
例如:
string mimeType = MimeMapping.GetMimeMapping(filename);
public void Configure(IApplicationBuilder app)
{
// Set up custom content types -associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos.
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "images")),
RequestPath = new PathString("/MyImages"),
ContentTypeProvider = provider
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "images")),
RequestPath = new PathString("/MyImages")
});
}
".Net框架提供了内置方法来获取MIME类型。无需编写自定义代码。"
"string mimeType = System.Web.MimeMapping.GetMimeMapping(fileName);"
Console.WriteLine("txt -> " + MimeTypeMap.GetMimeType("txt")); // "text/plain"
Console.WriteLine("audio/wav -> " + MimeTypeMap.GetExtension("audio/wav")); // ".wav"
您不应该相信来自客户端的文件扩展名。始终检查文件的魔数。
在ASP.NET Core中使用FileTpeInterrogator:
public static class FileTypeChecker
{
private static List<string> validVideoMimeTypes = new List<string> { "video/mp4", "video/quicktime" };
private static List<string> validImageMimeTypes = new List<string> { "image/png", "image/jpeg" };
public static bool IsValidVideo(IFormFile file)
{
return validVideoMimeTypes.Contains(GetFileMimeType(file));
}
public static bool IsValidImage(IFormFile file)
{
return validImageMimeTypes.Contains(GetFileMimeType(file));
}
private static string GetFileMimeType(IFormFile file)
{
// You should have checked for null and file length before reaching here
IFileTypeInterrogator interrogator = new FileTypeInterrogator.FileTypeInterrogator();
byte[] fileBytes;
using (var stream = new MemoryStream())
{
file.CopyTo(stream);
fileBytes = stream.ToArray();
}
FileTypeInfo fileTypeInfo = interrogator.DetectType(fileBytes);
return fileTypeInfo.MimeType.ToLower();
}
}
在你的控制器或服务中:
public IActionResult UploadVideo([FromForm] UploadVideoVM model)
{
if (model.File.Length < minimumLength || model.File.Length > maximumLength)
{
// BadRequest => Size
}
else if (!FileTypeChecker.IsValidVideo(model.File))
{
// BadRequest => Type
}
else
{
// All good
}
return Ok();
}
通过使用Apache列表,以下脚本将为您提供包含所有MIME类型的字典。
var mimeTypeListUrl = "http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types";
var webClient = new WebClient();
var rawData = webClient.DownloadString(mimeTypeListUrl).Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
var extensionToMimeType = new Dictionary<string, string>();
var mimeTypeToExtension = new Dictionary<string, string[]>();
foreach (var row in rawData)
{
if (row.StartsWith("#")) continue;
var rowData = row.Split(new[] { "\t" }, StringSplitOptions.RemoveEmptyEntries);
if (rowData.Length != 2) continue;
var extensions = rowData[1].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
if (!mimeTypeToExtension.ContainsKey(rowData[0]))
{
mimeTypeToExtension.Add(rowData[0], extensions);
}
foreach (var extension in extensions)
{
if (!extensionToMimeType.ContainsKey(extension))
{
extensionToMimeType.Add(extension, rowData[0]);
}
}
}
using Microsoft.Win32;
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
public static class Helper
{
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int ExtractIconEx(string lpszFile, int nIconIndex, IntPtr[] phIconLarge, IntPtr[] phIconSmall, int nIcons);
[DllImport("user32.dll", SetLastError = true)]
private static extern int DestroyIcon(IntPtr hIcon);
public static string GetFileContentType(string fileName)
{
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
RegistryKey registryKey = null;
try
{
FileInfo fileInfo = new FileInfo(fileName);
if (string.IsNullOrEmpty(fileInfo.Extension))
{
return string.Empty;
}
string extension = fileInfo.Extension.ToLowerInvariant();
registryKey = Registry.ClassesRoot.OpenSubKey(extension);
if (registryKey == null)
{
return string.Empty;
}
object contentTypeObject = registryKey.GetValue("Content Type");
if (!(contentTypeObject is string))
{
return string.Empty;
}
string contentType = (string)contentTypeObject;
return contentType;
}
catch (Exception)
{
return null;
}
finally
{
if (registryKey != null)
{
registryKey.Close();
}
}
}
public static string GetFileDescription(string fileName)
{
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
RegistryKey registryKey1 = null;
RegistryKey registryKey2 = null;
try
{
FileInfo fileInfo = new FileInfo(fileName);
if (string.IsNullOrEmpty(fileInfo.Extension))
{
return string.Empty;
}
string extension = fileInfo.Extension.ToLowerInvariant();
registryKey1 = Registry.ClassesRoot.OpenSubKey(extension);
if (registryKey1 == null)
{
return string.Empty;
}
object extensionDefaultObject = registryKey1.GetValue(null);
if (!(extensionDefaultObject is string))
{
return string.Empty;
}
string extensionDefaultValue = (string)extensionDefaultObject;
registryKey2 = Registry.ClassesRoot.OpenSubKey(extensionDefaultValue);
if (registryKey2 == null)
{
return string.Empty;
}
object fileDescriptionObject = registryKey2.GetValue(null);
if (!(fileDescriptionObject is string))
{
return string.Empty;
}
string fileDescription = (string)fileDescriptionObject;
return fileDescription;
}
catch (Exception)
{
return null;
}
finally
{
if (registryKey2 != null)
{
registryKey2.Close();
}
if (registryKey1 != null)
{
registryKey1.Close();
}
}
}
public static void GetFileIcons(string fileName, out Icon smallIcon, out Icon largeIcon)
{
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
smallIcon = null;
largeIcon = null;
RegistryKey registryKey1 = null;
RegistryKey registryKey2 = null;
try
{
FileInfo fileInfo = new FileInfo(fileName);
if (string.IsNullOrEmpty(fileInfo.Extension))
{
return;
}
string extension = fileInfo.Extension.ToLowerInvariant();
registryKey1 = Registry.ClassesRoot.OpenSubKey(extension);
if (registryKey1 == null)
{
return;
}
object extensionDefaultObject = registryKey1.GetValue(null);
if (!(extensionDefaultObject is string))
{
return;
}
string defaultIconKeyName = string.Format("{0}\\DefaultIcon", extensionDefaultObject);
registryKey2 = Registry.ClassesRoot.OpenSubKey(defaultIconKeyName);
if (registryKey2 == null)
{
return;
}
object defaultIconPathObject = registryKey2.GetValue(null);
if (!(defaultIconPathObject is string))
{
return;
}
string defaultIconPath = (string)defaultIconPathObject;
if (string.IsNullOrWhiteSpace(defaultIconPath))
{
return;
}
string iconfileName = null;
int iconIndex = 0;
int commaIndex = defaultIconPath.IndexOf(",");
if (commaIndex > 0)
{
iconfileName = defaultIconPath.Substring(0, commaIndex);
string iconIndexString = defaultIconPath.Substring(commaIndex + 1);
if (!int.TryParse(iconIndexString, out iconIndex))
{
iconIndex = 0;
}
}
else
{
iconfileName = defaultIconPath;
iconIndex = 0;
}
IntPtr[] phiconSmall = new IntPtr[1] { IntPtr.Zero };
IntPtr[] phiconLarge = new IntPtr[1] { IntPtr.Zero };
int readIconCount = ExtractIconEx(iconfileName, iconIndex, phiconLarge, phiconSmall, 1);
if (readIconCount < 0)
{
return;
}
if (phiconSmall[0] != IntPtr.Zero)
{
smallIcon = (Icon)Icon.FromHandle(phiconSmall[0]).Clone();
DestroyIcon(phiconSmall[0]);
}
if (phiconLarge[0] != IntPtr.Zero)
{
largeIcon = (Icon)Icon.FromHandle(phiconLarge[0]).Clone();
DestroyIcon(phiconLarge[0]);
}
return;
}
finally
{
if (registryKey2 != null)
{
registryKey2.Close();
}
if (registryKey1 != null)
{
registryKey1.Close();
}
}
}
}
string fileName = "NotExists.txt";
string contentType = Helper.GetFileContentType(fileName); // "text/plain"
string description = Helper.GetFileDescription(fileName); // "Text Document"
Icon smallIcon, largeIcon;
Helper.GetFileIcons(fileName, out smallIcon, out largeIcon); // 16x16, 32x32 icons