昨天的文章提到 .NET 4.5 內建 MimeMapping.GetMimeMapping(),可省去自己用 switch … case 逐一列舉副檔名對應ContentType 的工夫。

不過,這項福利僅限於 .NET 4.5+,如果程式使用的是 .NET 3.5 或 .NET 4.0,只能乖乖自己處理。理論上,新開發的程式用 .NET 4.5.2+ 名正言順(參考:  蛤,微軟停止.NET 4.0-4.5-4.5.1的技術支援?會對我的系統造成影響嗎?) BUT! 生活周遭總還是有 .NET 4.0/3.5/2.0 甚至 1.1 的線上系統,雖如風中蟾蜍,卻仍還需要擴充維護,所以... (我懂)

既然免不了要自己寫邏輯,除了查文件硬刻跟抄別人的程式,其實有個方法可以自動產生副檔名跟 ContentType 對照表。既然瀏覽器、.NET 4.5 MimeMapping 跟作業系統都知道什麼副檔案要對應什麼 ContentType,借用他們的資料來源自動產生即可。臉書專頁上有同學討論起針對 .NET 4.0 以下的做法,手癢難耐,決定動手實作玩一玩。

在 Windows 系統的 HKEY_CLASS_ROOT\MIME\Database\ContentType 機碼下有一份完整 ContentType 列表,其中 Extension 有該 ContentType 對應的副檔名,可視為權威資料來源:

因此,跑個迴圈讀 Registry,不費什麼力氣就能產生完整的 ContentType 與副檔名對應表囉!

    class Program
    {
        static void Main(string[] args)
        {
            var mimeReg = Registry.ClassesRoot
                    .OpenSubKey(@"MIME\Database\Content Type");
            var mimeMappings = new Dictionary<string, string>();
 
            mimeReg
            .GetSubKeyNames()
            .Where(o => mimeReg.OpenSubKey(o).GetValue("Extension") != null)
            .ToList()
            .ForEach(o =>
            {
                var ext = mimeReg.OpenSubKey(o).GetValue("Extension")
                          .ToString().Substring(1);
                if (mimeMappings.ContainsKey(ext))
                {
                    Console.WriteLine("[{0}] 重複設定 {1} & {2}", 
                        ext, mimeMappings[ext], o);
                }
                else
                {
                    mimeMappings.Add(ext, o);
                }
            });
 
            foreach (var key in mimeMappings.Keys.OrderBy(o => o))
            {
                Console.WriteLine($"{key} -> {mimeMappings[key]}");
            }
            Console.ReadLine();
        }
    }

程式裡有個小地方要特別處理:存在多個 ContentType 指向同一副檔名的情形,但反向對應時只能從中擇一。我的做法是保留第一筆並印出重複項目檢視。

執行結果發現 46 筆重複,取用第一筆的值應該也通用:

[pptx] 重複設定 application/vnd.ms-powerpoint.12 & application/vnd.openxmlformats-officedocument.presentationml.presentation
[xlsx] 重複設定 application/vnd.ms-excel.12 & application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
[docx] 重複設定 application/vnd.ms-word.document.12 & application/vnd.openxmlformats-officedocument.wordprocessingml.document
[dotx] 重複設定 application/vnd.ms-word.template.12 & application/vnd.openxmlformats-officedocument.wordprocessingml.template
[asx] 重複設定 application/x-mplayer2 & application/x-wmplayer
[cer] 重複設定 application/pkix-cert & application/x-x509-ca-cert
[zip] 重複設定 application/x-zip-compressed & application/zip
[mid] 重複設定 audio/mid & audio/midi
[m4a] 重複設定 audio/mp4 & audio/MP4A-LATM
[mp3] 重複設定 audio/mp3 & audio/mpeg
[mp3] 重複設定 audio/mp3 & audio/mpg
[ac3] 重複設定 audio/ac3 & audio/vnd.dolby.dd-raw
[aiff] 重複設定 audio/aiff & audio/x-aiff
[m4a] 重複設定 audio/mp4 & audio/x-m4a
[mid] 重複設定 audio/mid & audio/x-mid
[mid] 重複設定 audio/mid & audio/x-midi
[mp3] 重複設定 audio/mp3 & audio/x-mp3
[mp3] 重複設定 audio/mp3 & audio/x-mpeg
[m3u] 重複設定 audio/mpegurl & audio/x-mpegurl
[mp3] 重複設定 audio/mp3 & audio/x-mpg
[wav] 重複設定 audio/wav & audio/x-wav
[jpg] 重複設定 image/jpeg & image/pjpeg
[png] 重複設定 image/png & image/x-png
[mid] 重複設定 audio/mid & midi/mid
[p10] 重複設定 application/pkcs10 & pkcs10
[p7s] 重複設定 application/pkcs7-signature & pkcs7-signature
[cer] 重複設定 application/pkix-cert & pkix-cert
[crl] 重複設定 application/pkix-crl & pkix-crl
[vcf] 重複設定 text/directory & text/directory;profile=vCard
[vcf] 重複設定 text/directory & text/vcard
[vcf] 重複設定 text/directory & text/x-vcard
[xml] 重複設定 application/xml & text/xml
[mpeg] 重複設定 video/mpeg & video/mpg
[avi] 重複設定 video/avi & video/msvideo
[mpeg] 重複設定 video/mpeg & video/x-mpeg
[mpeg] 重複設定 video/mpeg & video/x-mpeg2a
[asx] 重複設定 application/x-mplayer2 & video/x-ms-asf
[asx] 重複設定 application/x-mplayer2 & video/x-ms-asf-plugin
[avi] 重複設定 video/avi & video/x-msvideo
[sst] 重複設定 application/vnd.ms-pki.certstore & vnd.ms-pki.certstore
[pko] 重複設定 application/vnd.ms-pki.pko & vnd.ms-pki.pko
[cat] 重複設定 application/vnd.ms-pki.seccat & vnd.ms-pki.seccat
[p12] 重複設定 application/x-pkcs12 & x-pkcs12
[p7b] 重複設定 application/x-pkcs7-certificates & x-pkcs7-certificates
[p7r] 重複設定 application/x-pkcs7-certreqresp & x-pkcs7-certreqresp
[cer] 重複設定 application/pkix-cert & x-x509-ca-cert

在我的 Windows 10 上,共找到 145 筆已知對應:

3g2 -> audio/3gpp2
3gp -> audio/3gpp
3gp2 -> video/3gpp2
3gpp -> video/3gpp
aac -> audio/aac
ac3 -> audio/ac3
accda -> application/msaccess.addin
accdb -> application/msaccess
accdc -> application/msaccess.cab
accde -> application/msaccess.exec
accdr -> application/msaccess.runtime
accdt -> application/msaccess.template
accdw -> application/msaccess.webapplication
accft -> application/msaccess.ftemplate
adts -> audio/vnd.dlna.adts
aiff -> audio/aiff
amr -> audio/amr
appcontent-ms -> application/windows-appcontent+xml
application -> application/x-ms-application
asx -> application/x-mplayer2
au -> audio/basic
avi -> video/avi
cat -> application/vnd.ms-pki.seccat
cer -> application/pkix-cert
contact -> text/x-ms-contact
crl -> application/pkix-crl
css -> text/css
dds -> image/vnd.ms-dds
dib -> image/bmp
doc -> application/msword
docm -> application/vnd.ms-word.document.macroEnabled.12
docx -> application/vnd.ms-word.document.12
dotm -> application/vnd.ms-word.template.macroEnabled.12
dotx -> application/vnd.ms-word.template.12
dtcp-ip -> application/x-dtcp1
dvr-ms -> video/x-ms-dvr
dwfx -> model/vnd.dwfx+xps
easmx -> model/vnd.easmx+xps
ec3 -> audio/ec3
edrwx -> model/vnd.edrwx+xps
emf -> image/x-emf
eprtx -> model/vnd.eprtx+xps
epub -> application/epub+zip
fif -> application/fractals
flac -> audio/x-flac
gif -> image/gif
gz -> application/x-gzip
hqx -> application/mac-binhex40
hta -> application/hta
htc -> text/x-component
html -> text/html
ico -> image/x-icon
ics -> text/calendar
iqy -> text/x-ms-iqy
jnlp -> application/x-java-jnlp-file
jpg -> image/jpeg
jtx -> application/x-jtx+xps
latex -> application/x-latex
lpcm -> audio/l16
m3u -> audio/mpegurl
m4a -> audio/mp4
m4r -> audio/x-m4r
m4v -> video/x-m4v
man -> application/x-troff-man
mid -> audio/mid
mka -> audio/x-matroska
mkv -> video/x-matroska
mov -> video/quicktime
mp3 -> audio/mp3
mp4 -> video/mp4
mpeg -> video/mpeg
nix -> application/x-mix-transfer
odc -> text/x-ms-odc
odp -> application/vnd.oasis.opendocument.presentation
ods -> application/vnd.oasis.opendocument.spreadsheet
odt -> application/vnd.oasis.opendocument.text
one -> application/msonenote
osdx -> application/opensearchdescription+xml
p10 -> application/pkcs10
p12 -> application/x-pkcs12
p7b -> application/x-pkcs7-certificates
p7c -> application/pkcs7-mime
p7m -> pkcs7-mime
p7r -> application/x-pkcs7-certreqresp
p7s -> application/pkcs7-signature
pdf -> application/pdf
pko -> application/vnd.ms-pki.pko
png -> image/png
potm -> application/vnd.ms-powerpoint.template.macroEnabled.12
potx -> application/vnd.openxmlformats-officedocument.presentationml.template
ppam -> application/vnd.ms-powerpoint.addin.macroEnabled.12
ppsm -> application/vnd.ms-powerpoint.slideshow.macroEnabled.12
ppsx -> application/vnd.openxmlformats-officedocument.presentationml.slideshow
ppt -> application/vnd.ms-powerpoint
pptm -> application/vnd.ms-powerpoint.presentation.macroEnabled.12
pptx -> application/vnd.ms-powerpoint.12
ps -> application/postscript
pub -> application/vnd.ms-publisher
rqy -> text/x-ms-rqy
sit -> application/x-stuffit
sldm -> application/vnd.ms-powerpoint.slide.macroEnabled.12
sldx -> application/vnd.openxmlformats-officedocument.presentationml.slide
solitairetheme8 -> application/x-compressed
spl -> application/futuresplash
sst -> application/vnd.ms-pki.certstore
svg -> image/svg+xml
swf -> application/x-shockwave-flash
tar -> application/x-tar
thmx -> application/vnd.ms-officetheme
tif -> image/tiff
tts -> video/vnd.dlna.mpeg-tts
txt -> text/plain
uvu -> video/vnd.dece.mp4
vcf -> text/directory
vsd -> application/vnd.ms-visio.viewer
vsto -> application/x-ms-vsto
wav -> audio/wav
wax -> audio/x-ms-wax
wdp -> image/vnd.ms-photo
website -> application/x-mswebsite
wm -> video/x-ms-wm
wma -> audio/x-ms-wma
wmd -> application/x-ms-wmd
wmf -> image/x-wmf
wmv -> video/x-ms-wmv
wmx -> video/x-ms-wmx
wmz -> application/x-ms-wmz
wpl -> application/vnd.ms-wpl
wsc -> text/scriptlet
wtv -> video/wtv
wvx -> video/x-ms-wvx
xaml -> application/xaml+xml
xbap -> application/x-ms-xbap
xht -> application/xhtml+xml
xlam -> application/vnd.ms-excel.addin.macroEnabled.12
xls -> application/vnd.ms-excel
xlsb -> application/vnd.ms-excel.sheet.binary.macroEnabled.12
xlsm -> application/vnd.ms-excel.sheet.macroEnabled.12
xlsx -> application/vnd.ms-excel.12
xltm -> application/vnd.ms-excel.template.macroEnabled.12
xltx -> application/vnd.openxmlformats-officedocument.spreadsheetml.template
xml -> application/xml
xps -> application/vnd.ms-xpsdocument
z -> application/x-compress
zip -> application/x-zip-compressed

掌握這個技巧,稍微包裝及調整一下,事先存成文字檔備查,或是即時查詢 Registry 建立 Dictionary<string, string> 都成,就能輕鬆寫出 .NET 2.0/3.5/4.0 版 GetMimeMapping() 囉~


Comments

# by hon

會否透過讀取 IIS 的MIME相關設定 找回副檔名相對應的content-type 會較方便? 應該可以避免出現"存在多個 ContentType 指向同一副檔名的情形"

# by Jeffrey

to hon, 參考IIS MIME map是個好主意。查了一下,設定寫在 \Windows\System32\inetsrv\config\applicationHost.config <system.webServer><staticContent><mimeMap>,要讀取可以透過Microsoft.Web.Administration.ServerManager.GetApplicationHostConfiguration()。參考: https://stackoverflow.com/a/3938245/288936

Post a comment