I am having the following issue when trying to make a post request to my orders controller. I am informed that certain fields are required, even though I have filled them in. Can anyone correct me on where I am going wrong here?
Here is my controller method:
public class OrdersController : ApiControllerBase
{
[HttpGet]
public async Task<ActionResult<OrdersViewModel>> GetOrderAsync()
{
return await Mediator.Send(new GetOrdersQuery());
}
[HttpPost]
[Produces("application/json")]
public async Task<ActionResult<bool>> Create(CreateOrderCommand command)
{
return await Mediator.Send(command);
}
}
Here is the CreateOrderCommand and its Handler:
[DataContract]
public class CreateOrderCommand : IRequest<bool>
{
[DataMember]
public string UserId { get; private set; }
[DataMember]
public string UserName { get; private set; }
[DataMember]
public string Street { get; private set; }
[DataMember]
public string City { get; private set; }
[DataMember]
public string Country { get; private set; }
[DataMember]
public string PostCode { get; private set; }
[DataMember]
public string CardNumber { get; private set; }
[DataMember]
public string CardHolderName { get; private set; }
[DataMember]
public DateTime ExpiryDate { get; private set; }
[DataMember]
public string CardSecurityNumber { get; private set; }
[DataMember]
public CardTypeEnum CardType { get; private set; }
[DataMember]
private readonly List<OrderItemDTO> _orderItems;
[DataMember]
public IEnumerable<OrderItemDTO> OrderItems => _orderItems;
public CreateOrderCommand()
{
_orderItems = new List<OrderItemDTO>();
}
public CreateOrderCommand(List<OrderItemDTO> orderItems, string userId, string userName, string city, string street, string country, string postcode,
string cardNumber, string cardHolderName, DateTime expiryDate, string cardSecurityNumber, CardTypeEnum cardType) : this()
{
_orderItems = orderItems;
UserId = userId;
UserName = userName;
City = city;
Street = street;
Country = country;
PostCode = postcode;
CardNumber = cardNumber;
CardHolderName = cardHolderName;
ExpiryDate = expiryDate;
CardSecurityNumber = cardSecurityNumber;
CardType = cardType;
}
}
public record OrderItemDTO
{
public decimal BookPrice { get; init; }
public string BookTitle { get; init; }
public int Quantity { get; init; }
public int BookCatalogueId { get; init; }
public string BookImageUrl { get; init; }
}
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, bool>
{
private readonly IOrderRepository _orderRepository;
private readonly ILogger<CreateOrderCommandHandler> _logger;
public CreateOrderCommandHandler(IOrderRepository orderRepository, ILogger<CreateOrderCommandHandler> logger)
{
_orderRepository = orderRepository;
_logger = logger;
}
public async Task<bool> Handle(CreateOrderCommand command, CancellationToken cancellationToken)
{
var deliveryAddress = new DeliveryAddress(command.Street, command.City, command.Country, command.PostCode);
var userId = (!string.IsNullOrEmpty(command.UserId)) ? command.UserId : "1";
var userName = (!string.IsNullOrEmpty(command.UserName)) ? command.UserName : "Christopher";
var order = new Order(userId, userName, deliveryAddress, command.CardType, command.CardNumber, command.CardSecurityNumber, command.CardHolderName, command.ExpiryDate);
if (order == null)
throw new NotFoundException();
foreach (var item in command.OrderItems)
{
order.AddOrderItem(item.BookCatalogueId, item.BookTitle, item.BookPrice, item.BookImageUrl, item.Quantity);
}
_logger.LogInformation("----- Creating Order - Order: {@Order}", order);
_orderRepository.Add(order);
return await _orderRepository.UnitOfWork
.SaveEntitiesAsync(cancellationToken);
}
}
}
Here is how I have registered my services:
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
{
services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
services.AddMediatR(Assembly.GetExecutingAssembly());
return services;
}
Here is my problem when I try to post a request to my controller:
CodePudding user response:
If you use the private setter, you cannot get the value. Change your model like below:
[DataContract]
public class CreateOrderCommand : IRequest<bool>
{
[DataMember]
public string UserId { get; set; } //remove all the private accessor...
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Street { get; set; }
[DataMember]
public string City { get; set; }
[DataMember]
public string Country { get; set; }
[DataMember]
public string PostCode { get; set; }
[DataMember]
public string CardNumber { get; set; }
[DataMember]
public string CardHolderName { get; set; }
[DataMember]
public DateTime ExpiryDate { get; set; }
[DataMember]
public string CardSecurityNumber { get; set; }
[DataMember]
public CardTypeEnum CardType { get; set; }
[DataMember]
private List<OrderItemDTO> _orderItems; //remove readonly
[DataMember]
public List<OrderItemDTO> OrderItems //change here..
{
get { return _orderItems; }
set { _orderItems = value; }
}
public CreateOrderCommand()
{
_orderItems = new List<OrderItemDTO>();
}
public CreateOrderCommand(List<OrderItemDTO> orderItems, string userId, string userName, string city, string street, string country, string postcode,
string cardNumber, string cardHolderName, DateTime expiryDate, string cardSecurityNumber,CardTypeEnum cardType) : this()
{
_orderItems = orderItems;
UserId = userId;
UserName = userName;
City = city;
Street = street;
Country = country;
PostCode = postcode;
CardNumber = cardNumber;
CardHolderName = cardHolderName;
ExpiryDate = expiryDate;
CardSecurityNumber = cardSecurityNumber;
CardType = cardType;
}
}