﻿# 認識 ASP.NET Core 內建的各種 Mime Types 用法

當我在研究 ASP.NET Core 的 [Response compression (回應壓縮) middleware](https://learn.microsoft.com/en-us/aspnet/core/performance/response-compression) 時，發現了 ASP.NET Core 內建支援各種 MIME Types 的相關支援，這篇文章我大致整理一下幾個常見的用法。

![aspnetcore-mime-types](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ca19e6cf8db9af765924-58b135c5-6f87-4d30-b4b9-e0aeff6b6a27.webp)

### ResponseCompressionDefaults.MimeTypes

我在 `Microsoft.AspNetCore.ResponseCompression` 命名空間下找到了一個 `ResponseCompressionDefaults.MimeTypes` 靜態屬性，這個屬性是一個 `IEnumerable<string>` 類型，裡面定義了哪些 MimeTypes 會在 Response compression middleware 中被預設壓縮，總共有 `10` 個：

-   `text/plain`
-   `text/css`
-   `application/javascript`
-   `text/javascript`
-   `text/html`
-   `application/xml`
-   `text/xml`
-   `application/json`
-   `text/json`
-   `application/wasm`

所以其他的 MIME Types 預設都不會進行回應壓縮，例如 `application/octet-stream` 預設就不會被壓縮。如果你想要增加 `application/octet-stream` 這個 MIME Type 的支援，可以這樣註冊到你的 `IServiceCollection` 之中：

```csharp
builder.Services.AddResponseCompression(options =>
{
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] {
        "application/octet-stream"
    });
});
```

### FileExtensionContentTypeProvider

我在 `Microsoft.AspNetCore.StaticFiles` 命名空間下找到了一個 `FileExtensionContentTypeProvider` 類別，這個類別專門用來處理各種 Content Type (內容類型) 相關的操作，也可以用來註冊新的 MIME Type 等等。

這個類別下只有兩個成員：

1.  `Mappings` 屬性 (Property)
    
    ```csharp
    using Microsoft.AspNetCore.StaticFiles;
    
    var ctp = new FileExtensionContentTypeProvider();
    
    // 你可以透過 ctp.Mappings 取得一個 Dictionary<String,String> 型別的物件
    ctp.Mappings.Dump();
    
    // 如果你想要取得不重複的 MIME Types 清單，可以這樣寫
    var mimeTypes = ctp.Mappings.Select(m => m.Value).Distinct();
    ```
    
    將所有的 MIME Type 加入 [Response compression middleware](https://learn.microsoft.com/en-us/aspnet/core/performance/response-compression) 就可以這樣定義：
    
    ```csharp
    builder.Services.AddResponseCompression(options =>
    {
        var ctp = new FileExtensionContentTypeProvider();
    
        options.MimeTypes = ctp.Mappings.Select(m => m.Value).Distinct();
    });
    ```
    
2.  `TryGetContentType` 方法
    
    如果你只是想判斷一個檔名相對應的 MIME Type，可以這樣寫：
    
    ```csharp
    using Microsoft.AspNetCore.StaticFiles;
    
    var ctp = new FileExtensionContentTypeProvider();
    
    ctp.TryGetContentType("test.flv", out var mimeType);
    mimeType.Dump(); // video/x-flv
    ```
    

這個 [FileExtensionContentTypeProvider](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0&WT.mc_id=DT-MVP-4015686#fileextensioncontenttypeprovider) 主要是給 [Static Files Middleware](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files) 使用的，如果你想要擴充或自訂 [Static Files Middleware](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files) 支援的 MIME Type，可以這樣寫：

```csharp
// 設定自訂的內容類型 - 將檔案副檔名與 MIME 類型關聯起來
var provider = new FileExtensionContentTypeProvider();

// 新增映射
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";

// 取代現有的映射
provider.Mappings[".rtf"] = "application/x-msdownload";

// 移除 MP4 影片
provider.Mappings.Remove(".mp4");

app.UseStaticFiles(new StaticFileOptions
{
    ContentTypeProvider = provider
});
```

### 相關連結

-   [Static files in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0&WT.mc_id=DT-MVP-4015686)
-   [Response compression in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-8.0&WT.mc_id=DT-MVP-4015686)
-   [Request decompression in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/request-decompression?view=aspnetcore-8.0&WT.mc_id=DT-MVP-4015686)
