Asp.Net Core 中,安裝 Swagger 非常方便,但我一直無法設定必要欄位,
目前只好自己寫一個 OperationFilter 來達到想要的功能。
首先安裝 Swagger,請參考這裡,安裝非常容易。
接下來讓我們自己產生 OperationFilter,參考以下程式碼
public class RequiredAttributeOperationFilter : IOperationFilter {
/// <summary>
///
/// </summary>
/// <param name="operation"></param>
/// <param name="context"></param>
public void Apply(Operation operation, OperationFilterContext context) {
//沒有參數
if (operation.Parameters == null) return;
for (int i = 0; i < operation.Parameters.Count; i++) {
var op_param = operation.Parameters[i];
//參數是 FromBody,就不處裡了
if (op_param.In.Equals("body")) continue;
//根據名稱找出 API 參數
var api_param = context.ApiDescription.ActionDescriptor.Parameters.FirstOrDefault(f => f.Name.Equals(op_param.Name)) as ControllerParameterDescriptor;
if (api_param != null) {
//檢查參數屬性有沒有 RequiredAttribute
if (api_param.ParameterInfo.CustomAttributes.Any(data => data.AttributeType == typeof(RequiredAttribute))) {
op_param.Required = true;
}
continue;
}
//根據名稱找出物件欄位
var field_param = context.ApiDescription.ParameterDescriptions.FirstOrDefault(f => f.Name.Equals(op_param.Name));
if (field_param != null) {
//檢查物件欄位有沒有 RequiredAttribute
var attrs = ((DefaultModelMetadata)field_param.ModelMetadata).Attributes.PropertyAttributes;
if (attrs != null && attrs.Any(attr => attr.GetType() == typeof(RequiredAttribute))) {
op_param.Required = true;
}
continue;
}
}
}
}
這裡有兩個參數 Operation 和 OperationFilterContext,
Operation 是紀錄 Web Api 的所有參數的顯示方式,是 Swagger 描述端點文檔的一部分。
OperationFilterContext 是 method 相關的資訊,這裡有兩個需要特別說明的地方,
讓我們舉個例子
public class UserProfile {
public string Name { get; set; }
public int Age { get; set; }
}
[HttpGet]
public string GetSomething(string id, UserProfile profile) {
...
}
如果 GetSomething 的參數有兩個,string 和 UserProfile,
那麼 OperationFilterContext.ApiDescription.ActionDescriptor.Parameters 就會有兩個 ParameterDescriptor 元素,
一個是 id, 另一個是 profile
而 OperationFilterContext.ApiDescription.ParameterDescriptions 會有三個 ApiParameterDescription 元素,
分別是 id、Name、Age。
若是在 GetSomething 的參數裡設定屬性,則只能在 ParameterDescriptor 找到,
而類別裡的欄位設定的屬性只能從 ApiParameterDescription 取得,
所以 RequiredAttributeOperationFilter 裡會先從參數找起,在去找欄位。
因此我們就可以設定成
public class UserProfile {
[Required]
public string Name { get; set; }
public int Age { get; set; }
}
[HttpGet]
public string GetSomething([Required]string id, UserProfile profile) {
...
}
這樣在 Swagger UI顯示 id 和 Name 參數時都會加上 (required) 說明,如下圖箭頭處