问题描述
只是想知道为什么当我发送带有数字 id
的 JSON 时:
{
"name": "yummy food","tags": [
{
"name": "Indian","id": "9","iconCodePoint": 23145
}
]
}
字段 Tags
以这样的数字 id 存储在数据库中:
但是字段 Tags
在响应中具有枚举 string
name 作为 id
字段:
{
"name": "yummy food","description": null,"image": null,"menuyItemRestaurants": null,"id": 7,"isNotVeganCount": 0,"isVeganCount": 0,"ratingsCount": 0,"rating": 0,"tags": [
{
"id": "Indian",<----------- HERE
"iconCodePoint": 23145,"name": "Indian"
}
],"establishments": null,"currentRevisionId": 0
}
添加更多字段的枚举的“类”版本:
using System.Text.Json.Serialization;
namespace Vepo.Domain
{
public class MenuItemTag
{
[JsonConstructor]
public MenuItemTag(string name,MenuItemTagEnum id,int iconCodePoint)
{
Id = id;
IconCodePoint = iconCodePoint;
Name = name;
}
public MenuItemTagEnum Id { get; set; }
public int IconCodePoint { get; set; }
public string Name { get; set; }
}
}
枚举:
public enum MenuItemTagEnum
{
Asian = 1,Barbecue,European,Bakery,Cafe,Deli,Desserts,FishAndChips,Indian,American,PubFood,Breakfast,Chinese,Fench,German,Japanese,Kebab,Mediterranian,LatinAmerican,MiddleEastern,Salad,Thai,Turkish,Vietnamese,Mexican,Sushi,Kiwi,Greek,HealthFood,Other,Korean,Italian
}
将 MenuItem.Tags
字段序列化为一个 string
表列的数据库上下文:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<MenuItemTag>()
.Property(tag => tag.Id)
.HasConversion<int>()
.ValueGeneratedNever();
builder.Entity<MenuItemTag>().HasData(
new MenuItemTag[] {
new MenuItemTag(
"American",MenuItemTagEnum.American,0xf803
),new MenuItemTag(
"Asian",MenuItemTagEnum.Asian,0xf823
),new MenuItemTag(
"Bakery",MenuItemTagEnum.Bakery,0xf705
),new MenuItemTag(
"Barbecue",MenuItemTagEnum.Barbecue,0xf80f
),new MenuItemTag(
"Breakfast",MenuItemTagEnum.Breakfast,0xe002
),new MenuItemTag(
"Cafe",MenuItemTagEnum.Cafe,0xf6c5
),new MenuItemTag(
"Chinese",MenuItemTagEnum.Chinese,new MenuItemTag(
"Deli",MenuItemTagEnum.Deli,0xf81f
),new MenuItemTag(
"Desserts",MenuItemTagEnum.Desserts,0xf551
),new MenuItemTag(
"European",MenuItemTagEnum.European,0xf7a2
),new MenuItemTag(
"Fish & Chips",MenuItemTagEnum.FishAndChips,0xf7fe
),new MenuItemTag(
"Indian",MenuItemTagEnum.Indian,0xf156
),new MenuItemTag(
"French",MenuItemTagEnum.Fench,0xf7f6
),new MenuItemTag(
"German",MenuItemTagEnum.German,0xf820
),new MenuItemTag(
"Greek",MenuItemTagEnum.Greek,0xf68b
),new MenuItemTag(
"Health Food",MenuItemTagEnum.HealthFood,0xf81e
),new MenuItemTag(
"Italian",MenuItemTagEnum.Italian,0xf817
),new MenuItemTag(
"Japanese",MenuItemTagEnum.Japanese,0xf56a
),new MenuItemTag(
"Kebab",MenuItemTagEnum.Kebab,0xf821
),new MenuItemTag(
"Kiwi",MenuItemTagEnum.Kiwi,0xf535
),new MenuItemTag(
"Korean",MenuItemTagEnum.Korean,0xf159
)});
builder.Entity<MenuItem>()
.Property(e => e.Tags)
.HasConversion(
v => JsonSerializer.Serialize(v,null),v => JsonSerializer.Deserialize<List<MenuItemTag>>(v,new ValueComparer<IList<MenuItemTag>>(
(c1,c2) => c1.SequenceEqual(c2),c => c.Aggregate(0,(a,v) => HashCode.Combine(a,v.GetHashCode())),c => (IList<MenuItemTag>)c.ToList()));
控制器:
// POST: api/MenuItems
// To protect from overposting attacks,see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPost]
public async Task<ActionResult<MenuItem>> PostMenuItem(MenuItem menuItem)
{
_context.MenuItems.Add(menuItem);
await _context.SaveChangesAsync();
return CreatedAtAction("GetMenuItem",new { id = menuItem.Id },menuItem);
}
知道如何将 MenuItem.Tags
的数据库转换器转换回 int
id 以发送 JSON 响应而不是字符串枚举名称吗?
我认为这段代码可以做到:
builder.Entity<MenuItemTag>()
.Property(tag => tag.Id)
.HasConversion<int>()
.ValueGeneratedNever();
解决方法
您可以轻松设置自己的转换
.HasConversion() => {
set => Enum.GetName(typeof(<YourEnum>),set),get => {
<your switch case>
}
}
我已经在我当前的项目中使用 List 做到了这一点。
我写了一个“获取转换函数”的小PoC:
Conversion Example
Implementation Example/PoC Switch