【问题标题】:File extensions and MIME Types in .NET.NET 中的文件扩展名和 MIME 类型
【发布时间】:2010-12-09 10:12:00
【问题描述】:

我想从给定的扩展中获取 MIME 内容类型(最好不访问物理文件)。我已经看到了一些关于此的问题,并且可以在以下位置恢复描述的执行此操作的方法:

  1. 使用registry information
  2. 使用urlmon.dll's FindMimeFromData
  3. 使用IIS information
  4. 滚动您自己的 MIME 映射函数。例如,基于this table

我使用no.1有一段时间了,但我意识到注册表提供的信息并不一致,取决于机器上安装的软件。某些扩展名,例如 .zip 不用于指定 Content-Type。

解决方案 2 强制我将文件保存在磁盘上以便读取第一个字节,这很慢,但可能会得到很好的结果。

第三种方法基于目录服务和所有这些东西,这是我不太喜欢的东西,因为我必须添加 COM 引用并且我不确定它在 IIS6 和 IIS7 之间是否一致。另外,我不知道这种方法的性能。

最后,我不想使用自己的表格,但如果我想要在平台(甚至是 Mono)之间获得良好的性能和结果的一致性,这似乎是最好的选择。

您认为有比使用我自己的表格更好的选择还是其他描述的方法更好?你有什么经验?

【问题讨论】:

    标签: .net asp.net content-type mime file-extension


    【解决方案1】:

    这取决于您需要 MIME 类型的用途。一般来说,对于服务(Web 应用程序、Web 服务等),建议不要使用依赖于操作系统设置的 MIME 列表,或者仅在您无法找到 MIME 信息时作为备用。

    我认为这也是 MS 选择将常量 MIME 类型放入其System.Web.MimeMapping 类的原因(不幸的是,无论出于何种原因,它都是内部的)。

    编辑:

    包装器 (
    public static class MimeExtensionHelper
    {
        static object locker = new object();
        static object mimeMapping;
        static MethodInfo getMimeMappingMethodInfo;
    
        static MimeExtensionHelper()
        {
            Type mimeMappingType = Assembly.GetAssembly(typeof(HttpRuntime)).GetType("System.Web.MimeMapping");
            if (mimeMappingType == null)
                throw new SystemException("Couldnt find MimeMapping type");
            ConstructorInfo constructorInfo = mimeMappingType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
            if (constructorInfo == null)
                throw new SystemException("Couldnt find default constructor for MimeMapping");
            mimeMapping = constructorInfo.Invoke(null);
            if (mimeMapping == null)
                throw new SystemException("Couldnt find MimeMapping");
            getMimeMappingMethodInfo = mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic);
            if (getMimeMappingMethodInfo == null)
                throw new SystemException("Couldnt find GetMimeMapping method");
            if (getMimeMappingMethodInfo.ReturnType != typeof(string))
                throw new SystemException("GetMimeMapping method has invalid return type");
            if (getMimeMappingMethodInfo.GetParameters().Length != 1 && getMimeMappingMethodInfo.GetParameters()[0].ParameterType != typeof(string))
                throw new SystemException("GetMimeMapping method has invalid parameters");
        }
        public static string GetMimeType(string filename)
        {
            lock (locker)
                return (string)getMimeMappingMethodInfo.Invoke(mimeMapping, new object[] { filename });
        }
    }
    

    包装器 (.NET 4.0)

    public static class MimeExtensionHelper
        {
            static object locker = new object();
            static object mimeMapping;
            static MethodInfo getMimeMappingMethodInfo;
    
            static MimeExtensionHelper()
            {
                Type mimeMappingType = Assembly.GetAssembly(typeof(HttpRuntime)).GetType("System.Web.MimeMapping");
                if (mimeMappingType == null)
                    throw new SystemException("Couldnt find MimeMapping type");            
                getMimeMappingMethodInfo = mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                if (getMimeMappingMethodInfo == null)
                    throw new SystemException("Couldnt find GetMimeMapping method");
                if (getMimeMappingMethodInfo.ReturnType != typeof(string))
                    throw new SystemException("GetMimeMapping method has invalid return type");
                if (getMimeMappingMethodInfo.GetParameters().Length != 1 && getMimeMappingMethodInfo.GetParameters()[0].ParameterType != typeof(string))
                    throw new SystemException("GetMimeMapping method has invalid parameters");
            }
            public static string GetMimeType(string filename)
            {
                lock (locker)
                    return (string)getMimeMappingMethodInfo.Invoke(mimeMapping, new object[] { filename });
            }
        }
    

    .NET 4.5+

    不需要包装器,直接调用公共方法System.Web.MimeMapping.GetMimeMapping

    【讨论】:

    • 可能值得注意的是,在 .NET 4.5 中这是完全公开的,不需要任何反射 msdn.microsoft.com/en-us/library/…
    • @rudi_visser,感谢您的提示 - 最后 MS 注意到这不仅仅是他们自己的代码所需要的。 :)
    • 对于 .jpeg 它返回 application/octet-stream 这不是我所期望的。我想要image/jpg
    • @Tymek, @harpo:GetMimeMapping 函数需要一个文件名,而不仅仅是扩展名。
    • var mimetype = System.Web.MimeMapping.GetMimeMapping(filenamewithext) - 这很棒,不必是文件路径,甚至不会访问文件 - 从逻辑上讲,它需要'的最后一个索引。并从图书馆获取
    【解决方案2】:

    我已经在我的实用程序库中结合了所有这些方法,也许没有 3。 顺便说一句,no.2 (urlmon.dll) 不需要静态文件,它只需要一些字节,无论它们来自哪里。 这是我目前的课程

    namespace Components
    {
        using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Runtime.InteropServices;
        using System.Text;
        using System.Xml.Serialization;
        using Microsoft.Win32;
    
        public sealed class MimeExtensionHelper
        {
            private MimeExtensionHelper() { }
    
            /// <summary>Finds extension associated with specified mime type</summary>
            /// <param name="mimeType">mime type you search extension for, e.g.: "application/octet-stream"</param>
            /// <returns>most used extension, associated with provided type, e.g.: ".bin"</returns>
            public static string FindExtension(string mimeType)
            {
                return ExtensionTypes.GetExtension(mimeType);
            }
    
            /// <summary>Finds mime type using provided extension and/or file's binary content.</summary>
            /// <param name="file">Full file path</param>
            /// <param name="verifyFromContent">Should the file's content be examined to verify founded value.</param>
            /// <returns>mime type of file, e.g.: "application/octet-stream"</returns>
            public static string FindMime(string file,bool verifyFromContent)
            {
                string extension = Path.GetExtension(file);
                string mimeType = string.Empty;
                try
                {
                    if (!String.IsNullOrEmpty(extension))
                        mimeType = ExtensionTypes.GetMimeType(extension);
                    if (verifyFromContent
                        || (String.IsNullOrEmpty(mimeType) && File.Exists(file)))
                        mimeType = FindMimeByContent(file,mimeType);
                }
                catch { }
                return (mimeType ?? string.Empty).Trim();//"application/octet-stream"
            }
    
            /// <summary>Finds mime type for file using it's binary data.</summary>
            /// <param name="file">Full path to file.</param>
            /// <param name="proposedType">Optional. Expected file's type.</param>
            /// <returns>mime type, e.g.: "application/octet-stream"</returns>
            public static string FindMimeByContent(string file
                ,string proposedType)
            {
                FileInfo fi = new FileInfo(file);
                if (!fi.Exists)
                    throw new FileNotFoundException(file);
                byte[] buf = new byte[Math.Min(4096L,fi.Length)];
                using (FileStream fs = File.OpenRead(file))
                    fs.Read(buf,0,buf.Length);
                return FindMimeByData(buf,proposedType);
            }
    
            /// <summary>Finds mime type for binary data.</summary>
            /// <param name="dataBytes">Binary data to examine.</param>
            /// <param name="mimeProposed">Optional. Expected mime type.</param>
            /// <returns>mime type, e.g.: "application/octet-stream"</returns>
            public static string FindMimeByData(byte[] dataBytes,string mimeProposed)
            {
                if (dataBytes == null || dataBytes.Length == 0)
                    throw new ArgumentNullException("dataBytes");
                string mimeRet = String.Empty;
                IntPtr outPtr = IntPtr.Zero;
                if (!String.IsNullOrEmpty(mimeProposed))
                    mimeRet = mimeProposed;
                int result = FindMimeFromData(IntPtr.Zero
                    ,null
                    ,dataBytes
                    ,dataBytes.Length
                    ,String.IsNullOrEmpty(mimeProposed) ? null : mimeProposed
                    ,0
                    ,out outPtr
                    ,0);
                if (result != 0)
                    throw Marshal.GetExceptionForHR(result);
                if (outPtr != null && outPtr != IntPtr.Zero)
                {
                    mimeRet = Marshal.PtrToStringUni(outPtr);
                    Marshal.FreeCoTaskMem(outPtr);
                }
                return mimeRet;
            }
    
            [DllImport("urlmon.dll"
                ,CharSet = CharSet.Unicode
                ,ExactSpelling = true
                ,SetLastError = true)]
            static extern Int32 FindMimeFromData(IntPtr pBC
                ,[MarshalAs(UnmanagedType.LPWStr)] String pwzUrl
                ,[MarshalAs(UnmanagedType.LPArray,ArraySubType = UnmanagedType.I1,SizeParamIndex = 3)] Byte[] pBuffer
                ,Int32 cbSize
                ,[MarshalAs(UnmanagedType.LPWStr)] String pwzMimeProposed
                ,Int32 dwMimeFlags
                ,out IntPtr ppwzMimeOut
                ,Int32 dwReserved);
    
            private static MimeTypeCollection _extensionTypes = null;
            private static MimeTypeCollection ExtensionTypes
            {
                get
                {
                    if (_extensionTypes == null)
                        _extensionTypes = new MimeTypeCollection();
                    return _extensionTypes;
                }
            }
    
            [Serializable]
            [XmlRoot(ElementName = "mimeTypes")]
            private class MimeTypeCollection : List<MimeTypeCollection.mimeTypeInfo>
            {
                private SortedList<string,string> _extensions;
                private SortedList<string,List<string>> _mimes;
    
                private void Init()
                {
                    if (_extensions == null || _mimes == null
                        || _extensions.Count == 0 || _mimes.Count == 0)
                    {
                        _extensions = new SortedList<string,string>(StringComparer.OrdinalIgnoreCase);
                        _mimes = new SortedList<string,List<string>>(StringComparer.OrdinalIgnoreCase);
                        foreach (var mime in this)
                        {
                            _mimes.Add(mime.MimeType,new List<string>(mime.Extensions));
                            foreach (string ext in mime.Extensions)
                                if (!_extensions.ContainsKey(ext))
                                    _extensions.Add(ext,mime.MimeType);
                        }
                    }
                }
    
                public String GetExtension(string type)
                {
                    Init();
                    return _mimes.ContainsKey(type) ? _mimes[type][0] : string.Empty;
                }
    
                public String GetMimeType(string extension)
                {
                    Init();
                    return _extensions.ContainsKey(extension) ? _extensions[extension] : string.Empty;
                }
    
            public MimeTypeCollection()
            {
                this.Add(new mimeTypeInfo("application/applixware",new List<string>(new[] { ".aw" })));
                this.Add(new mimeTypeInfo("application/atom+xml",new List<string>(new[] { ".atom" })));
                // ... Whole list from apache's site
                this.Add(new mimeTypeInfo("x-x509-ca-cert",new List<string>(new[] { ".cer" })));
                try
                {
                    using (RegistryKey classesRoot = Registry.ClassesRoot)
                    using (RegistryKey typeKey = classesRoot.OpenSubKey(@"MIME\Database\Content Type"))
                    {
                        string[] subKeyNames = typeKey.GetSubKeyNames();
                        string extension = string.Empty;
                        foreach (string keyname in subKeyNames)
                        {
                            string trimmed = (keyname ?? string.Empty).Trim();
                            if (string.IsNullOrEmpty(trimmed))
                                continue;
                            if (!String.IsNullOrEmpty(GetExtension(trimmed)))
                                continue;
                            string subKey = "MIME\\Database\\Content Type\\" + trimmed;
                            using (RegistryKey curKey = classesRoot.OpenSubKey(subKey))
                            {
                                extension = (curKey.GetValue("Extension") as string ?? string.Empty).Trim();
                                if (extension.Length > 0)
                                    this.Add(new mimeTypeInfo(trimmed
                                        ,new List<string>(new[] { extension })));
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    string s = ex.ToString();
                }
            }
    
            [Serializable]
            public class mimeTypeInfo
            {
                [XmlAttribute(AttributeName = "mimeType")]
                public String MimeType { get; set; }
    
                [XmlElement("extension")]
                public List<String> Extensions { get; set; }
    
                public mimeTypeInfo(string mimeType,List<string> extensions)
                {
                    MimeType = mimeType;
                    Extensions = extensions;
                }
    
                public mimeTypeInfo() { }
            }
        }
    }
    

    }

    【讨论】:

      【解决方案3】:

      System.Web.MimeMapping 有 3 个版本 - 两个 4.0 版本(其中一个是内部的),然后是 2.0 版本,它也是内部的。正如所指出的,System.Web 4.0 版中有一个用于 .NET 4.5 框架的类的公共版本。

      对于 RoadkillWiki,我基本上已经对其进行了逆向工程,以节省每次反射的麻烦,Wiki 的文件处理程序默认尝试使用 IIS/applicationhost.config,然后落入 MimeMapping 类:

      private string GetMimeType(string fileExtension, ServerManager serverManager)
      {
          try
          {
              string mimeType = "text/plain";
      
              Microsoft.Web.Administration.Configuration config = serverManager.GetApplicationHostConfiguration();
              ConfigurationSection staticContentSection = config.GetSection("system.webServer/staticContent");
              ConfigurationElementCollection mimemaps = staticContentSection.GetCollection();
      
              ConfigurationElement element = mimemaps.FirstOrDefault(m => m.Attributes["fileExtension"].Value.ToString() == fileExtension);
      
              if (element != null)
                  mimeType = element.Attributes["mimeType"].Value.ToString();
      
              return mimeType;
          }
          catch (UnauthorizedAccessException)
          {
              // Shared hosting won't have access to the applicationhost.config file
              return MimeMapping.GetMimeMapping("." +fileExtension);
          }
      }
      

      还有 MimeMapping:

      public class MimeMapping
      {
          private static Dictionary<string, string> ExtensionMap = new Dictionary<string, string>();
      
          static MimeMapping()
          {
              ExtensionMap.Add(".323", "text/h323");
              ExtensionMap.Add(".asx", "video/x-ms-asf");
              ExtensionMap.Add(".acx", "application/internet-property-stream");
              ExtensionMap.Add(".ai", "application/postscript");
              ExtensionMap.Add(".aif", "audio/x-aiff");
              ExtensionMap.Add(".aiff", "audio/aiff");
              ExtensionMap.Add(".axs", "application/olescript");
              ExtensionMap.Add(".aifc", "audio/aiff");
              ExtensionMap.Add(".asr", "video/x-ms-asf");
              ExtensionMap.Add(".avi", "video/x-msvideo");
              ExtensionMap.Add(".asf", "video/x-ms-asf");
              ExtensionMap.Add(".au", "audio/basic");
              ExtensionMap.Add(".application", "application/x-ms-application");
              ExtensionMap.Add(".bin", "application/octet-stream");
              ExtensionMap.Add(".bas", "text/plain");
              ExtensionMap.Add(".bcpio", "application/x-bcpio");
              ExtensionMap.Add(".bmp", "image/bmp");
              ExtensionMap.Add(".cdf", "application/x-cdf");
              ExtensionMap.Add(".cat", "application/vndms-pkiseccat");
              ExtensionMap.Add(".crt", "application/x-x509-ca-cert");
              ExtensionMap.Add(".c", "text/plain");
              ExtensionMap.Add(".css", "text/css");
              ExtensionMap.Add(".cer", "application/x-x509-ca-cert");
              ExtensionMap.Add(".crl", "application/pkix-crl");
              ExtensionMap.Add(".cmx", "image/x-cmx");
              ExtensionMap.Add(".csh", "application/x-csh");
              ExtensionMap.Add(".cod", "image/cis-cod");
              ExtensionMap.Add(".cpio", "application/x-cpio");
              ExtensionMap.Add(".clp", "application/x-msclip");
              ExtensionMap.Add(".crd", "application/x-mscardfile");
              ExtensionMap.Add(".deploy", "application/octet-stream");
              ExtensionMap.Add(".dll", "application/x-msdownload");
              ExtensionMap.Add(".dot", "application/msword");
              ExtensionMap.Add(".doc", "application/msword");
              ExtensionMap.Add(".dvi", "application/x-dvi");
              ExtensionMap.Add(".dir", "application/x-director");
              ExtensionMap.Add(".dxr", "application/x-director");
              ExtensionMap.Add(".der", "application/x-x509-ca-cert");
              ExtensionMap.Add(".dib", "image/bmp");
              ExtensionMap.Add(".dcr", "application/x-director");
              ExtensionMap.Add(".disco", "text/xml");
              ExtensionMap.Add(".exe", "application/octet-stream");
              ExtensionMap.Add(".etx", "text/x-setext");
              ExtensionMap.Add(".evy", "application/envoy");
              ExtensionMap.Add(".eml", "message/rfc822");
              ExtensionMap.Add(".eps", "application/postscript");
              ExtensionMap.Add(".flr", "x-world/x-vrml");
              ExtensionMap.Add(".fif", "application/fractals");
              ExtensionMap.Add(".gtar", "application/x-gtar");
              ExtensionMap.Add(".gif", "image/gif");
              ExtensionMap.Add(".gz", "application/x-gzip");
              ExtensionMap.Add(".hta", "application/hta");
              ExtensionMap.Add(".htc", "text/x-component");
              ExtensionMap.Add(".htt", "text/webviewhtml");
              ExtensionMap.Add(".h", "text/plain");
              ExtensionMap.Add(".hdf", "application/x-hdf");
              ExtensionMap.Add(".hlp", "application/winhlp");
              ExtensionMap.Add(".html", "text/html");
              ExtensionMap.Add(".htm", "text/html");
              ExtensionMap.Add(".hqx", "application/mac-binhex40");
              ExtensionMap.Add(".isp", "application/x-internet-signup");
              ExtensionMap.Add(".iii", "application/x-iphone");
              ExtensionMap.Add(".ief", "image/ief");
              ExtensionMap.Add(".ivf", "video/x-ivf");
              ExtensionMap.Add(".ins", "application/x-internet-signup");
              ExtensionMap.Add(".ico", "image/x-icon");
              ExtensionMap.Add(".jpg", "image/jpeg");
              ExtensionMap.Add(".jfif", "image/pjpeg");
              ExtensionMap.Add(".jpe", "image/jpeg");
              ExtensionMap.Add(".jpeg", "image/jpeg");
              ExtensionMap.Add(".js", "application/x-javascript");
              ExtensionMap.Add(".lsx", "video/x-la-asf");
              ExtensionMap.Add(".latex", "application/x-latex");
              ExtensionMap.Add(".lsf", "video/x-la-asf");
              ExtensionMap.Add(".manifest", "application/x-ms-manifest");
              ExtensionMap.Add(".mhtml", "message/rfc822");
              ExtensionMap.Add(".mny", "application/x-msmoney");
              ExtensionMap.Add(".mht", "message/rfc822");
              ExtensionMap.Add(".mid", "audio/mid");
              ExtensionMap.Add(".mpv2", "video/mpeg");
              ExtensionMap.Add(".man", "application/x-troff-man");
              ExtensionMap.Add(".mvb", "application/x-msmediaview");
              ExtensionMap.Add(".mpeg", "video/mpeg");
              ExtensionMap.Add(".m3u", "audio/x-mpegurl");
              ExtensionMap.Add(".mdb", "application/x-msaccess");
              ExtensionMap.Add(".mpp", "application/vnd.ms-project");
              ExtensionMap.Add(".m1v", "video/mpeg");
              ExtensionMap.Add(".mpa", "video/mpeg");
              ExtensionMap.Add(".me", "application/x-troff-me");
              ExtensionMap.Add(".m13", "application/x-msmediaview");
              ExtensionMap.Add(".movie", "video/x-sgi-movie");
              ExtensionMap.Add(".m14", "application/x-msmediaview");
              ExtensionMap.Add(".mpe", "video/mpeg");
              ExtensionMap.Add(".mp2", "video/mpeg");
              ExtensionMap.Add(".mov", "video/quicktime");
              ExtensionMap.Add(".mp3", "audio/mpeg");
              ExtensionMap.Add(".mpg", "video/mpeg");
              ExtensionMap.Add(".ms", "application/x-troff-ms");
              ExtensionMap.Add(".nc", "application/x-netcdf");
              ExtensionMap.Add(".nws", "message/rfc822");
              ExtensionMap.Add(".oda", "application/oda");
              ExtensionMap.Add(".ods", "application/oleobject");
              ExtensionMap.Add(".pmc", "application/x-perfmon");
              ExtensionMap.Add(".p7r", "application/x-pkcs7-certreqresp");
              ExtensionMap.Add(".p7b", "application/x-pkcs7-certificates");
              ExtensionMap.Add(".p7s", "application/pkcs7-signature");
              ExtensionMap.Add(".pmw", "application/x-perfmon");
              ExtensionMap.Add(".ps", "application/postscript");
              ExtensionMap.Add(".p7c", "application/pkcs7-mime");
              ExtensionMap.Add(".pbm", "image/x-portable-bitmap");
              ExtensionMap.Add(".ppm", "image/x-portable-pixmap");
              ExtensionMap.Add(".pub", "application/x-mspublisher");
              ExtensionMap.Add(".pnm", "image/x-portable-anymap");
              ExtensionMap.Add(".pml", "application/x-perfmon");
              ExtensionMap.Add(".p10", "application/pkcs10");
              ExtensionMap.Add(".pfx", "application/x-pkcs12");
              ExtensionMap.Add(".p12", "application/x-pkcs12");
              ExtensionMap.Add(".pdf", "application/pdf");
              ExtensionMap.Add(".pps", "application/vnd.ms-powerpoint");
              ExtensionMap.Add(".p7m", "application/pkcs7-mime");
              ExtensionMap.Add(".pko", "application/vndms-pkipko");
              ExtensionMap.Add(".ppt", "application/vnd.ms-powerpoint");
              ExtensionMap.Add(".pmr", "application/x-perfmon");
              ExtensionMap.Add(".pma", "application/x-perfmon");
              ExtensionMap.Add(".pot", "application/vnd.ms-powerpoint");
              ExtensionMap.Add(".prf", "application/pics-rules");
              ExtensionMap.Add(".pgm", "image/x-portable-graymap");
              ExtensionMap.Add(".qt", "video/quicktime");
              ExtensionMap.Add(".ra", "audio/x-pn-realaudio");
              ExtensionMap.Add(".rgb", "image/x-rgb");
              ExtensionMap.Add(".ram", "audio/x-pn-realaudio");
              ExtensionMap.Add(".rmi", "audio/mid");
              ExtensionMap.Add(".ras", "image/x-cmu-raster");
              ExtensionMap.Add(".roff", "application/x-troff");
              ExtensionMap.Add(".rtf", "application/rtf");
              ExtensionMap.Add(".rtx", "text/richtext");
              ExtensionMap.Add(".sv4crc", "application/x-sv4crc");
              ExtensionMap.Add(".spc", "application/x-pkcs7-certificates");
              ExtensionMap.Add(".setreg", "application/set-registration-initiation");
              ExtensionMap.Add(".snd", "audio/basic");
              ExtensionMap.Add(".stl", "application/vndms-pkistl");
              ExtensionMap.Add(".setpay", "application/set-payment-initiation");
              ExtensionMap.Add(".stm", "text/html");
              ExtensionMap.Add(".shar", "application/x-shar");
              ExtensionMap.Add(".sh", "application/x-sh");
              ExtensionMap.Add(".sit", "application/x-stuffit");
              ExtensionMap.Add(".spl", "application/futuresplash");
              ExtensionMap.Add(".sct", "text/scriptlet");
              ExtensionMap.Add(".scd", "application/x-msschedule");
              ExtensionMap.Add(".sst", "application/vndms-pkicertstore");
              ExtensionMap.Add(".src", "application/x-wais-source");
              ExtensionMap.Add(".sv4cpio", "application/x-sv4cpio");
              ExtensionMap.Add(".tex", "application/x-tex");
              ExtensionMap.Add(".tgz", "application/x-compressed");
              ExtensionMap.Add(".t", "application/x-troff");
              ExtensionMap.Add(".tar", "application/x-tar");
              ExtensionMap.Add(".tr", "application/x-troff");
              ExtensionMap.Add(".tif", "image/tiff");
              ExtensionMap.Add(".txt", "text/plain");
              ExtensionMap.Add(".texinfo", "application/x-texinfo");
              ExtensionMap.Add(".trm", "application/x-msterminal");
              ExtensionMap.Add(".tiff", "image/tiff");
              ExtensionMap.Add(".tcl", "application/x-tcl");
              ExtensionMap.Add(".texi", "application/x-texinfo");
              ExtensionMap.Add(".tsv", "text/tab-separated-values");
              ExtensionMap.Add(".ustar", "application/x-ustar");
              ExtensionMap.Add(".uls", "text/iuls");
              ExtensionMap.Add(".vcf", "text/x-vcard");
              ExtensionMap.Add(".wps", "application/vnd.ms-works");
              ExtensionMap.Add(".wav", "audio/wav");
              ExtensionMap.Add(".wrz", "x-world/x-vrml");
              ExtensionMap.Add(".wri", "application/x-mswrite");
              ExtensionMap.Add(".wks", "application/vnd.ms-works");
              ExtensionMap.Add(".wmf", "application/x-msmetafile");
              ExtensionMap.Add(".wcm", "application/vnd.ms-works");
              ExtensionMap.Add(".wrl", "x-world/x-vrml");
              ExtensionMap.Add(".wdb", "application/vnd.ms-works");
              ExtensionMap.Add(".wsdl", "text/xml");
              ExtensionMap.Add(".xml", "text/xml");
              ExtensionMap.Add(".xlm", "application/vnd.ms-excel");
              ExtensionMap.Add(".xaf", "x-world/x-vrml");
              ExtensionMap.Add(".xla", "application/vnd.ms-excel");
              ExtensionMap.Add(".xls", "application/vnd.ms-excel");
              ExtensionMap.Add(".xof", "x-world/x-vrml");
              ExtensionMap.Add(".xlt", "application/vnd.ms-excel");
              ExtensionMap.Add(".xlc", "application/vnd.ms-excel");
              ExtensionMap.Add(".xsl", "text/xml");
              ExtensionMap.Add(".xbm", "image/x-xbitmap");
              ExtensionMap.Add(".xlw", "application/vnd.ms-excel");
              ExtensionMap.Add(".xpm", "image/x-xpixmap");
              ExtensionMap.Add(".xwd", "image/x-xwindowdump");
              ExtensionMap.Add(".xsd", "text/xml");
              ExtensionMap.Add(".z", "application/x-compress");
              ExtensionMap.Add(".zip", "application/x-zip-compressed");
              ExtensionMap.Add(".*", "application/octet-stream");
          }
      
          public static string GetMimeMapping(string fileExtension)
          {
              if (ExtensionMap.ContainsKey(fileExtension))
                  return ExtensionMap[fileExtension];
              else
                  return ExtensionMap[".*"];
          }
      }
      

      【讨论】:

        【解决方案4】:

        我编写了一个程序来获取 Apache mime.types 文件并将其转换为由文件扩展名键入的 C# Dictionary&lt;string, string&gt;。在这里:

        https://github.com/cymen/ApacheMimeTypesToDotNet

        实际输出的是这个文件:

        https://github.com/cymen/ApacheMimeTypesToDotNet/blob/master/ApacheMimeTypes.cs

        希望其他人也觉得它有用!

        【讨论】:

          【解决方案5】:

          Nisus - 您愿意将您的实用程序的完整源代码发布到某个地方吗?那真的很有帮助。谢谢!

          没关系……

          我将 apache 定义文件编辑为仅包含具有已定义扩展名的条目,然后扩展代码以在运行时从文本文件加载类型/扩展名。可能并不优雅,但肯定优于为 mime 类型创建/维护 630 行源代码。

          [在 MimeTypeCollection 的构造函数中,而不是这些东西: this.Add(new mimeTypeInfo("application/applixware",new List(new[] { ".aw" })));]

                  // import mime/extension definition list to facilitate maintenance
              string dir = AppDomain.CurrentDomain.BaseDirectory;
              using (TextReader streamReader = new StreamReader(Path.Combine(dir, "MimeDefinitions.txt")))
              {
                string input;
                while ((input = streamReader.ReadLine()) != null)
                {
                  if (input.Substring(0, 1) != "#")
                  {
                    // text line format ::= [contenttype]<tab>[space delimited list of extensions, without dot]
                    string contentType = input.Group("0\t1");
                    string extensionList = input.Group("1\t1");
                    string[] extensions = extensionList.Split(" ".ToCharArray());
                    List<string> extensionSet = new List<string>();
                    foreach (string term in extensions)
                    {
                      extensionSet.Add("."+term);
                    }
                    this.Add(new mimeTypeInfo(contentType, extensionSet));
                  }
                }
              }
          

          我还发现会调用 Init() 方法,而 _extensions 和 _mime 成员不会完全初始化,所以我将其更改为:

          if (_extensions == null || _mimes == null || _mimes.Count != this.Count)
          

          无论如何,我现在如何处理我需要的外部 defs 和本地注册表的类。

          谢谢!

          【讨论】:

            【解决方案6】:

            我还发现 Init() 方法会被调用,而 _extensions 和 _mime 成员不会完全初始化,所以我将其更改为读取,最好的方法是从 MimeTypeCollection 中删除构造函数中的调用 GetExtension:

                    public MimeTypeCollection()
                    {
                        this.Add(new mimeTypeInfo("application/applixware", new List<string>(new[] { ".aw" })));
                        this.Add(new mimeTypeInfo("application/atom+xml", new List<string>(new[] { ".atom" })));
                        // ... Whole list from apache's site
                        this.Add(new mimeTypeInfo("x-x509-ca-cert", new List<string>(new[] { ".cer" })));
                        try
                        {
                            using (RegistryKey classesRoot = Registry.ClassesRoot)
                            using (RegistryKey typeKey = classesRoot.OpenSubKey(@"MIME\Database\Content Type"))
                            {
                                string[] subKeyNames = typeKey.GetSubKeyNames();
                                string extension = string.Empty;
                                foreach (string keyname in subKeyNames)
                                {
                                    string trimmed = (keyname ?? string.Empty).Trim();
                                    if (string.IsNullOrEmpty(trimmed))
                                        continue;
                                    if (this.Exists(mime => mime.MimeType == trimmed))
                                        continue;
                                    //if (!String.IsNullOrEmpty(GetExtension(trimmed)))
                                    //  continue;
                                    string subKey = "MIME\\Database\\Content Type\\" + trimmed;
                                    using (RegistryKey curKey = classesRoot.OpenSubKey(subKey))
                                    {
                                        extension = (curKey.GetValue("Extension") as string ?? string.Empty).Trim();
                                        if (extension.Length > 0)
                                            this.Add(new mimeTypeInfo(trimmed
                                                    , new List<string>(new[] { extension })));
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            string s = ex.ToString();
                        }
                    }
            

            【讨论】:

              【解决方案7】:

              我想提醒您不要在未根据文件的实际内容验证文件的情况下检索文件的 Mime / 内容类型,因为这可能会给您的系统和用户带来严重的安全风险。

              尽管存在类似这样的有效用例,但攻击者可能通过将可执行文件或脚本伪装成其他非可疑文件类型来攻击您的系统或将其用作将恶意文件传播给其他用户的机制。

              建议您在继续处理(或使其可供下载)之前认真考虑对上传的文件进行沙盒处理并对文件执行深度内容检查。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-09-23
                • 2010-11-05
                • 2010-10-03
                • 2019-09-24
                • 2011-05-14
                • 1970-01-01
                相关资源
                最近更新 更多