使用 Enum 的好處很多,可以有強型別又有 intellisense 提示,還可以增加閱讀性,但在 WebAPI 中要將 Enum 的值輸出時,有點不如期待,他會用數字代碼來當作 JSON 的值,這樣有點不方便閱讀,這裡提供 3 種方法,讓你用簡單的方式,把 Enum 用有意義的文字做輸出。
假設你有個 Enum 來標示產品狀態,產品模型和 Enum 狀態的程式碼長得像下面這樣:
public class Product
{
public string Name { get; set; }
public Status Status { get; set; }
}
public enum Status
{
Normal,
Warning,
Error
}
如果透過下面的 Controller 把一群產品狀態丟回前端時:
public class ValueController : ControllerBase
{
// GET api/value
[HttpGet]
public IActionResult Get()
{
var productList = new List<Product>()
{
new Product(){ Name= "A", Status = Status.Normal},
new Product(){ Name= "B", Status = Status.Warning},
new Product(){ Name= "C", Status = Status.Error}
};
return new JsonResult(productList);
}
}
會得到的回應資料會長這樣:
[
{
"name": "A",
"status": 0
},
{
"name": "B",
"status": 1
},
{
"name": "C",
"status": 2
}
]
這樣的狀態資訊是不容易閱讀的,這時候你可能會想到拿到的有意義的文字,而不是用數字代碼來表達。
解法一:在 Startup.cs
設定 JSON 序列化
這時候你可以在 Startup.cs
檔案中,在 AddMvc
加入 JSON 的序列化設定,下面的程式碼會將 Enum 轉成 JSON 時用名稱替代,並且忽略 JSON 中 Null 的屬性值。
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
});
}
}
解法二:在 Enum 上加上 JsonConverter (Newtonsoft.Json)
不過上面這個解法我沒有很喜歡,我喜歡下面這一種,不在這麼頂層的地方處理,而是在靠近模型的地方操作,這樣對我來說比較容易記憶用途。
因此在不修改 Startup.cs
檔案的前提下,Enum 可以使用 Json.NET 的 JsonConverter
搭配內建的 StringEnumConverter
處理,參考下面的寫法:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace API.Models
{
[JsonConverter(typeof(StringEnumConverter))]
public enum Status
{
Normal,
Warning,
Error
}
}
會得到的回應資料會長這樣:
[
{
"name": "A",
"status": "Normal"
},
{
"name": "B",
"status": "Warning"
},
{
"name": "C",
"status": "Error"
}
]
是不是變得比較容易閱讀了。
解法三:在 Enum 上加上 JsonConverter (System.Text.Json)
後來 System.Text.Json
也有推出相同的處理方式,只是要使用 JsonStringEnumConverter
來處理,參考下面的寫法:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace API.Models
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Status
{
Normal,
Warning,
Error
}
}
最後一種方式,是我最喜歡的。
自訂輸出文字
如果你想要自訂輸出的文字,Enum
可以加上 System.Runtime.Serialization
的 EnumMemberAttribute
來做覆寫,參考下面的寫法:
using System.Runtime.Serialization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace API.Models
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Status
{
[EnumMember(Value = "It's Normal")]
Normal,
[EnumMember(Value = "It's Warning")]
Warning,
[EnumMember(Value = "It's Error")]
Error
}
}
這樣結果就變成:
[
{
"name": "A",
"status": "It's Normal"
},
{
"name": "B",
"status": "It's Warning"
},
{
"name": "C",
"status": "It's Error"
}
]
參考資料: