C# ASP.NET Core 6 指定預設 Media type 為 application/json

在建立完 ASP.NET Core 6 API 專案後(預設已經安裝 Swashbuckle.AspNetCore 套件),直接打開 Swagger UI 網頁會發現 API 的 Media type 有三個,分別是 text/plain, application/json, text/json

通常我們最常用的就是 application/json ,該如何指定回應的 Media type 呢?使用 ProducesAttribute 就可以了:
    
    [HttpGet(Name = "GetWeatherForecast")]
    [Produces("application/json")]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
    }
    

每一個都需要這樣指定很麻煩,有沒有辦法只要沒有使用 Produces 註解指定 Media type 的 API 預設就設定 Media type 為 application/json 呢?

經過多次嘗試,筆者發現要單純指定但是不影響到其他回應內容範例有點小難,不過筆者有研究出一個偷吃步的方式,就是只要沒有 Produces 註解就把預設 Media type 的另外兩個移除:

建立自訂過濾器:
    
public class JsonOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // 檢查是否有 ProducesAttribute。
        var hasProducesAttribute = context.MethodInfo
            .GetCustomAttributes(true)
            .Union(context.MethodInfo.DeclaringType?.GetCustomAttributes(true) ?? Array.Empty<object>())
            .OfType<ProducesAttribute>()
            .Any();

        if (hasProducesAttribute) return;
        foreach (var response in operation.Responses)
        {
            response.Value.Content.Remove("text/plain");
            response.Value.Content.Remove("text/json");
        }
    }
}
    

在 Program.cs 中註冊:
    
// builder.Services.AddSwaggerGen(); // 預設應該有這行,替換為下面的

builder.Services.AddSwaggerGen(options =>
{
    options.OperationFilter<JsonOperationFilter>();
});

    

這樣除非有手動指定,不然預設就會是 application/json 了!

留言