Невозможно привести объект типа AsyncStateMachineBox System.Threading.Tasks.VoidTaskResult к типу System.Threading.Tasks.Task

Я новичок в веб-API ASP.NET и пытаюсь использовать внедрение зависимостей Entity Framework Core для данных POST в контроллер API с использованием шаблона MediatR. Но каждый раз, когда я запускаю свой код и он открывает пользовательский интерфейс Swagger, я получаю ответ с ошибкой 500, говорящий

Не удалось преобразовать объект типа «AsyncStateMachineBox1[System.Threading.Tasks.VoidTaskResult,S3E1.Repository.CartItemRepository+<Createitem>d__5]' to type 'System.Threading.Tasks.Task1[S3E1.Entities.CartItemEntity]».

Во-первых, я добавил внедрение зависимостей в Program.cs.

//Dependency Injection
builder.Services.AddDbContext<AppDataContext>(contextOptions => contextOptions.UseSqlServer(
    builder.Configuration.GetConnectionString("DefaultConnection")
    ));

//Connection
builder.Services.AddSingleton<DataConnectionContext>();

Это классы. AppDataContext.cs

public class AppDataContext : DbContext
    {
        
        public AppDataContext(DbContextOptions<AppDataContext> contextOptions) : base(contextOptions) { }

        public DbSet<CartItemEntity> CartItems { get; set; }
      
        public DbSet<OrderEntity> Orders { get; set; }

        public DbSet<UserEntity> Users{ get; set; }
        
    }

DataConnectionContext.cs

public class DataConnectionContext
    {
        private readonly IConfiguration _configuration;
        private readonly string _connectionString;

        public DataConnectionContext(IConfiguration configuration)
        {
            _configuration = configuration;
            _connectionString = _configuration.GetConnectionString("DefaultConnection");
        }

        public IDbConnection CreateConnection() => new SqlConnection(_connectionString);
    }

Далее создается репозиторий, содержащий интерфейс с методом create.

public interface ICartItemRepository
    {
        //public Task<IEnumerable<CartItemEntity>> GetCartItems();
        //public Task<CartItemEntity> GetCartItemEntity(Guid id);

        public Task Createitem(CartItemEntity itemEntity);
    }

Затем класс, который наследует интерфейс и вызывает конструкторы зависимостей

public class CartItemRepository : ICartItemRepository
    {

private readonly DataConnectionContext _connectionContext;
        private readonly AppDataContext _appDataContext;

        public CartItemRepository(DataConnectionContext connectionContext, AppDataContext appDataContext)
        {
            _connectionContext = connectionContext;
            _appDataContext = appDataContext;
        }

public async Task Createitem(CartItemEntity itemEntity)
        {
            _appDataContext.CartItems.Add(itemEntity);
            await _appDataContext.SaveChangesAsync();
            await _appDataContext.CartItems.ToListAsync();
        }
}

Далее идет команда для шаблона MediatR запроса POST.

public record AddCartItemCommand(CartItemEntity cartItem) : IRequest<CartItemEntity>;

и обработчик, который управляет и возвращает метод createitem

public class AddItemsHandler : IRequestHandler<AddCartItemCommand, CartItemEntity>
    {
        private readonly ICartItemRepository _cartItemRepository;

        public AddItemsHandler(ICartItemRepository cartItemRepository) => _cartItemRepository = cartItemRepository;

        public async Task<CartItemEntity> Handle(AddCartItemCommand request, CancellationToken cancellationToken)
        {
            return await (Task<CartItemEntity>) _cartItemRepository.Createitem(request.cartItem);
        }
    }

и, наконец, в контроллере

[Route("api/cart-items")]
    [ApiController]
    public class CartItemsController : ControllerBase
    {
        private ISender _sender;

        public CartItemsController(ISender sender) => _sender = sender;


[HttpPost]
        public async Task<CartItemEntity> Post(CartItemEntity cartItemEntity)
        {
            return await _sender.Send(new AddCartItemCommand(cartItemEntity));
        }
}

Я попытался изменить возвращаемый объект в обработчике, но каждый раз, когда я что-либо меняю, он всегда получает волнистую строку с ошибкой, поэтому я просто применил (Task) после ожидания. Это где я ошибся? Спасибо за любые ответы.

Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
0
482
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Исключение понятно. Вы не можете бросить VoidTaskResult на Task<CartItemEntity>.

Решить проблему:

  1. В ICartItemRepository измените тип возвращаемого значения для Createitem на Task<CartItemEntity>.

  2. В CartItemRepository реализуйте метод Createitem из интерфейса ICartItemRepository. Верните вставленный itemEntity в метод.

  3. Поскольку вы реализовали Task<CartItemEntity> Createitem(CartItemEntity itemEntity) в интерфейсе ICartItemRepository, приведение к (Task<CartItemEntity>) больше не нужно, и его предлагается удалить.

public interface ICartItemRepository
{
    ...

    public Task<CartItemEntity> Createitem(CartItemEntity itemEntity);
}
public class CartItemRepository : ICartItemRepository
{
    ...

    public async Task<CartItemEntity> Createitem(CartItemEntity itemEntity)
    {
        _appDataContext.CartItems.Add(itemEntity);
        await _appDataContext.SaveChangesAsync();

        return itemEntity;
    }
}
public class AddItemsHandler : IRequestHandler<AddCartItemCommand, CartItemEntity>
{
    ...

    public async Task<CartItemEntity> Handle(AddCartItemCommand request, CancellationToken cancellationToken)
    {
         return await _cartItemRepository.Createitem(request.cartItem);
    }
}

Большое спасибо за это, недавно я только что изучил шаблоны MediatR, поэтому передача нескольких запросов и команд обработчикам сбивала с толку.

TroyUrtiz 11.11.2022 08:13

Другие вопросы по теме