Почему мой ValueConverter с ValueComparer для преобразования Enum в класс не работает?C#

Место общения программистов C#
Ответить
Anonymous
 Почему мой ValueConverter с ValueComparer для преобразования Enum в класс не работает?

Сообщение Anonymous »

Я пытаюсь отправить этот JSON в свой API с помощью Postman:

Код: Выделить всё

{
"name": "yummy food",
"brand": "brand",
"tags": [
"1",
"2"
]
}
Но я получаю следующую ошибку:

Код: Выделить всё

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-b7a6042817b5124294f5c6d2f6169f05-70d797d0744bfe40-00",
"errors": {
"$.tags[0]": [
"The JSON value could not be converted to GroceryItemTag.  Path: $.tags[0] | LineNumber: 4 | BytePositionInLine: 11."
]
}
}
Поле GroceryItemTag («теги») в публикации представляет собой перечисление, но в качестве объекта GroceryItemTag используется таблица поиска с полями идентификатора перечисления, имени и iconCodePoint.< /p>
Запрос почтальона:
Изображение

Вот моя модель Entity Framework Core:
GroceryItem :

Код: Выделить всё

using System.Collections.Generic;

namespace Vepo.Domain
{
public class GroceryItem : VeganItem
{
public string Name {get; set;}
public string Brand {get; set;}
public string Description {get; set;}
public string Image {get; set;}
public virtual ICollection GroceryItemGroceryStores { get; set; }

}
}
Базовый класс GroceryItem (обратите внимание на виртуальные теги с идентификаторами тегов):

Код: Выделить всё

using System.Collections.Generic;

namespace Vepo.Domain
{
public abstract class VeganItem
{
public int Id { get; set; }
public int IsNotVeganCount { get; set; }
public int IsVeganCount { get; set; }
public int RatingsCount { get; set; }
public int Rating { get; set; }
public List TagIds { get; set; }
public virtual List Tags { get; set; }

public List Establishments { get; set; }
public int CurrentRevisionId { get; set; }

}
}
GroceryItemTageEnum:

Код: Выделить всё

public enum GroceryItemTagEnum
{
BabyAndChild = 1,
Baking,
Bathroom,
BeerAndWine,
Condiments,
Confectionary,
Cooking,
Dessert,
Drinks,
FauxDairy,
FauxMeat,
FauxSeafood,
FridgeAndDeli,
Frozen,
HealthFood,
HouseHold,
Other,
Pantry,
Pet,
}
Класс GroceryItemTag для таблицы поиска:

Код: Выделить всё

public class GroceryItemTag
{
public GroceryItemTagEnum Id { get; set; }
public int IconCodePoint {get; set;}
public string Name { get; set; }
}
Контроллер, обратите внимание на PostGroceryItem:

Код: Выделить всё

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Vepo.Domain;

namespace Vepo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class GroceryItemsController : ControllerBase
{
private readonly VepoContext _context;

public GroceryItemsController(VepoContext context)
{
_context = context;
}

// GET: api/GroceryItems
[HttpGet]
public async Task GetGroceryItems()
{
return await _context.GroceryItems.ToListAsync();
}

// GET: api/GroceryItems/5
[HttpGet("{id}")]
public async Task GetGroceryItem(int id)
{
var groceryItem = await _context.GroceryItems.FindAsync(id);

if (groceryItem == null)
{
return NotFound();
}

return groceryItem;
}

// PUT: api/GroceryItems/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPut("{id}")]
public async Task  PutGroceryItem(int id, GroceryItem groceryItem)
{
if (id != groceryItem.Id)
{
return BadRequest();
}

_context.Entry(groceryItem).State = EntityState.Modified;

try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!GroceryItemExists(id))
{
return NotFound();
}
else
{
throw;
}
}

return NoContent();
}

// POST: api/GroceryItems
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPost]
public async Task PostGroceryItem(GroceryItem groceryItem)
{
_context.GroceryItems.Add(groceryItem);
await _context.SaveChangesAsync();

return CreatedAtAction("GetGroceryItem", new { id = groceryItem.Id }, groceryItem);
}

// DELETE: api/GroceryItems/5
[HttpDelete("{id}")]
public async Task DeleteGroceryItem(int id)
{
var groceryItem = await _context.GroceryItems.FindAsync(id);
if (groceryItem == null)
{
return NotFound();
}

_context.GroceryItems.Remove(groceryItem);
await _context.SaveChangesAsync();

return NoContent();
}

private bool GroceryItemExists(int id)
{
return _context.GroceryItems.Any(e => e.Id == id);
}
}
}
Мой контекст базы данных, который создает таблицу поиска GroceryItemTag:

Код: Выделить всё

using Microsoft.EntityFrameworkCore;

namespace Vepo.Domain
{
public class VepoContext : DbContext
{
public VepoContext(DbContextOptions options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity().HasKey(table => new
{
table.GroceryItemId,
table.GroceryStoreId
});

builder.Entity().HasKey(table => new
{
table.MenuItemId,
table.RestaurantId
});

builder.Entity()
.Property(tag => tag.Id)
.ValueGeneratedNever();

builder.Entity()
.Property(tag => tag.Id)
.ValueGeneratedNever();

builder.Entity().HasData(
new GroceryItemTag[] {
new GroceryItemTag {
Name = "Baby & Child",
Id = GroceryItemTagEnum.BabyAndChild,
IconCodePoint = 0xf77c
},
new GroceryItemTag {
Name = "Baking",
Id = GroceryItemTagEnum.Baking,
IconCodePoint = 0xf563
},
new GroceryItemTag {
Name = "Beer &  Wine",
Id = GroceryItemTagEnum.BeerAndWine,
IconCodePoint = 0xf4e3
},
new GroceryItemTag {
Name = "Condiments",
Id = GroceryItemTagEnum.Condiments,
IconCodePoint = 0xf72f
},
new GroceryItemTag {
Name = "Confectionary",
Id = GroceryItemTagEnum.Confectionary,
IconCodePoint = 0xf819
},
new GroceryItemTag {
Name = "Cooking",
Id = GroceryItemTagEnum.Cooking,
IconCodePoint = 0xe01d
},
new GroceryItemTag {
Name = "Dessert",
Id = GroceryItemTagEnum.Dessert,
IconCodePoint = 0xf810
},
new GroceryItemTag {
Name = "Drinks",
Id = GroceryItemTagEnum.Drinks,
IconCodePoint = 0xf804
},
new GroceryItemTag {
Name = "Faux Meat",
Id = GroceryItemTagEnum.FauxMeat,
IconCodePoint = 0xf814
},
new GroceryItemTag {
Name = "Faux Dairy",
Id = GroceryItemTagEnum.FauxDairy,
IconCodePoint = 0xf7f0
},
new GroceryItemTag {
Name = "Faux Seafood",
Id = GroceryItemTagEnum.FauxSeafood,
IconCodePoint = 0xf7fe
},
new GroceryItemTag {
Name = "Fridge & Deli",
Id = GroceryItemTagEnum.FridgeAndDeli,
IconCodePoint = 0xe026
},
new GroceryItemTag {
Name = "Frozen",
Id = GroceryItemTagEnum.Frozen,
IconCodePoint = 0xf7ad
},
new GroceryItemTag {
Name = "Bathroom",
Id = GroceryItemTagEnum.Bathroom,
IconCodePoint = 0xe06b
},
new GroceryItemTag {
Name = "Health Food",
Id = GroceryItemTagEnum.HealthFood,
IconCodePoint = 0xf787
},
new GroceryItemTag {
Name = "Household",
Id = GroceryItemTagEnum.HouseHold,
IconCodePoint = 0xf898
},
new GroceryItemTag {
Name = "Pantry",
Id = GroceryItemTagEnum.Pantry,
IconCodePoint = 0xf7eb
},
new GroceryItemTag {
Name = "Pet",
Id = GroceryItemTagEnum.Pet,
IconCodePoint = 0xf6d3
},
new GroceryItemTag {
Name = "Other",
Id = GroceryItemTagEnum.Other,
IconCodePoint = 0xf39b
}});

builder.Entity()
.Property(e => e.Tags)
.HasConversion(
v => JsonSerializer.Serialize(v, null),
v => JsonSerializer.Deserialize(v, null),
new ValueComparer(
(c1, c2) => c1.SequenceEqual(c2),
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
c => (IList)c.ToList()));

}

public DbSet GroceryItems { get; set; }
public DbSet GroceryItemGroceryStores { get; set; }
public DbSet MenuItemRestaurants { get; set; }
public DbSet MenuItems { get; set; }
public DbSet GroceryStores { get; set; }
public DbSet GroceryItemTags { get; set; }
public DbSet MenuItemTags { get; set; }
public DbSet  Restaurants { get; set; }
}
}
Как отправить сообщение от почтальона, который сможет преобразовать идентификатор тега в GroceryItemTag
Я знаю, что я необходимо сделать это (см. официальную документацию Microsoft):

Код: Выделить всё

    builder.Entity()
.Property(e => e.Tags)
.HasConversion(
v => JsonSerializer.Serialize(v, null),
v => JsonSerializer.Deserialize(v, null),
new ValueComparer(
(c1, c2) => c1.SequenceEqual(c2),
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
c => (IList)c.ToList()));
Я просто не могу заставить его работать, например, он компилируется, но получаю ту же ошибку. Никаких изменений.

Подробнее здесь: https://stackoverflow.com/questions/665 ... -not-worki
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»