在建立完 ASP.NET Core 6 API 專案後(預設已經安裝 Swashbuckle.AspNetCore 套件),直接打開 Swagger UI 網頁會發現 API 的 Media type 有三個,分別是 text/plain, application/json, text/json
通常我們最常用的就是 application/json ,該如何指定回應的 Media type 呢?使用 ProducesAttribute 就可以了:
每一個都需要這樣指定很麻煩,有沒有辦法只要沒有使用 Produces 註解指定 Media type 的 API 預設就設定 Media type 為 application/json 呢?
經過多次嘗試,筆者發現要單純指定但是不影響到其他回應內容範例有點小難,不過筆者有研究出一個偷吃步的方式,就是只要沒有 Produces 註解就把預設 Media type 的另外兩個移除:
建立自訂過濾器:
在 Program.cs 中註冊:
這樣除非有手動指定,不然預設就會是 application/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 了!
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com