POST JSON 对象,枚举 id 作为数字,响应返回枚举字符串名称而不是 int id

问题描述 投票:0回答:1

只是想知道为什么当我发送带有数字的 JSON

id
:

{
    "name": "yummy food",
    "tags": [
        {
            "name": "Indian",
            "id": "9",
            "iconCodePoint": 23145
        }
    ]
}

字段

Tags
存储在数据库中,其数字 ID 如下所示:

enter image description here

但是字段

Tags
具有枚举
string 
名称作为响应中的
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,
            0xf823
        ),
        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, null),
        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();
json asp.net-core serialization entity-framework-core json-serialization
1个回答
0
投票

您可以轻松设置自己的转换

.HasConversion() => {
    set => Enum.GetName(typeof(<YourEnum>), set),
    get => {
      <your switch case>
    }
}

我已经在我当前的项目中使用列表做到了这一点。
我写了一些“获取转换函数”的PoC:
转换示例
实现示例/PoC交换机

© www.soinside.com 2019 - 2024. All rights reserved.