微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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

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

字段 Tags 以这样的数字 id 存储在数据库中:

enter image description here

但是字段 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。