Home > front end >  Unable to cast object of type AsyncStateMachineBox System.Threading.Tasks.VoidTaskResult to type Sys
Unable to cast object of type AsyncStateMachineBox System.Threading.Tasks.VoidTaskResult to type Sys

Time:11-11

I'm very new to ASP.NET Web API and I'm trying to use Entity Framework Core's Dependency Injection to POST data to the API Controller using MediatR pattern. But every time I run my code and it opens Swagger UI, I get an error 500 response saying

Unable to cast object of type 'AsyncStateMachineBox1[System.Threading.Tasks.VoidTaskResult,S3E1.Repository.CartItemRepository <Createitem>d__5]' to type 'System.Threading.Tasks.Task1[S3E1.Entities.CartItemEntity]'.

First, I added Dependency Injections to Program.cs

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

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

These are the classes. 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);
    }

Next is making a repository which holds the interface that has the create method.

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

        public Task Createitem(CartItemEntity itemEntity);
    }

Then a class that inherits the interface and calls the dependency constructors

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();
        }
}

Next is a command for POST request MediatR pattern

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

and a Handler which manages and returns the method 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);
        }
    }

and lastly, in the controller

[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));
        }
}

I tried modifying the return object in the handler but every time I change anything it always get the error squiggly line, so I just casted the (Task) after the await. Is this where I went wrong? Thank you for any answers.

CodePudding user response:

The exception is clear. You can't cast a VoidTaskResult to Task<CartItemEntity>.

To solve the problem:

  1. In ICartItemRepository, modify the return type for Createitem as Task<CartItemEntity>.

  2. In CartItemRepository, implement Createitem method from the ICartItemRepository interface. Return the inserted itemEntity in the method.

  3. Since you have implemented Task<CartItemEntity> Createitem(CartItemEntity itemEntity) in the ICartItemRepository interface, the casting to (Task<CartItemEntity>) is no longer needed, and suggested to be removed.

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);
    }
}
  • Related