'ASP.Net Core MVC - API with post gives error 400 Bad Request

I have an MVC controller which I use for an API endpoint as well. There is a model for viewing, a model for the API request, and a data model.

While using Postman, I get a 400 error. I don't see any description of the reason for the error. I removed authentication to test the API. Postman error 400 Bad Request

ContainerViewModel

public class ContainerViewModel
{
    public Guid ID { get; set; }
    public string Nickname { get; set; }
    public IEnumerable<ItemViewModel> Items { get; set; }

    public class ItemViewModel
    {
        public Guid ID { get; set; }
        public string Nickname { get; set; }
        public uint Quantity { get; set; }
    }
}

ContainerRequestModel

public class ContainerRequestModel
{
    public string Nickname { get; set; }
    public ItemRequestModel[] Items { get; set; }

    public class ItemRequestModel
    {
        public string Nickname { get; set; }
        public uint Quantity { get; set; }
    }
}

Container

public class Container
{
    public Guid ID { get; set; }
    public string Nickname { get; set; }
    public IEnumerable<ItemRequestModel> Items { get; set; }

    public class Item
    {
        public Guid ID { get; set; }
        public string Nickname { get; set; }
        public uint Quantity { get; set; }
    }
}

ContainerController

public class ContainerController : Controller
{
    private readonly IContainerManager _manager;

    public PurchaseOrdersController(IContainerManager manager)
    {
        _manager = manager;
    }

    public async Task<IActionResult> Index(CancellationToken token)
    {
        return View((await _manager.List(token))
            .Select(e => PrepareViewModel(data: e)));
    }

    [HttpPost]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult<Container>> ApiCreate(ContainerRequestModel containerRM, CancellationToken token)
    {
        var container = PrepareDataModel(containerRM);
        await _manager.Add(container, token); // Adds the data to persistence
        return container;
    }

    private PurchaseOrderViewModel PrepareViewModel(
        ContainerViewModel vm = null,
        Container data = null)
    {
        vm ??= new ContainerViewModel();
        vm.Items ??= new();
        if (data != null) {
            vm.ID = data.ID;
            vm.Nickname = data.Nickname;
            vm.Items.AddRange(data.Items.Select(e => new ContainerViewModel.ItemViewModel {
                ID = e.ID,
                Nickname = e.Nickname,
                Quantity = e.Quantity
            }));
        }
        return vm;
    }

    private Container PrepareDataModel(ContainerRequestModel rm)
    {
        var ct = new Container() {
            ID = Guid.NewGuid(),
            Nickname = rm.Nickname
        };
        ct.Items = rm.Items.Select(e => new Container.Item {
            ID = Guid.NewGuid(),
            Nickname = e.Nickname,
            Quantity = e.Quantity,
            Parent = ct
        }).ToList();
        return ct;
    }
}

Program.cs


app.MapControllerRoute(
    name: "api",
    pattern: "api/{*endpoint}",
    defaults: new { controller = "Containers", action = "ApiCreate" });
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Containers}/{action=Index}/{id?}");
app.MapRazorPages();

app.Run();


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source