I'm trying to write this controller that accepts a POST request.
I need this controller to add a new book, and also add that new books bookId to another object called a StoreList.
So I am trying to pass in the new bookList, and the storeList that needs the bookId added to it.
// POST: api/BookList
[HttpPost]
public async Task<ActionResult<BookList>> PostBookList(BookList bookList, StoreList storeList)
{
_context.BookList.Add(bookList);
await _context.SaveChangesAsync();
_context.Entry(storeList).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!StoreListExists(storeId))
{
return NotFound();
}
else
{
throw;
}
}
return CreatedAtAction("GetBookList", new { id = bookList.BookId }, bookList);
}
Here is my API endpoint:
And these are the two objects I'm passing in the BODY of the request (the new bookList and the existing storeList):
{
"bookId": "bc381612-c63b-4438-b35b-161a3a568fc7",
"bookTitle": "Is this a test 2?"
},
{
"storeId": "0001f801-6909-4b6e-8652-e1b49745280f",
"bookId": "bc381612-c63b-4438-b35b-161a3a568fc7"
}
But whenever I try to 'hit' that endpoint, I get this error:
System.InvalidOperationException HResult=0x80131509 Message=Action 'DocumentStorageAPI.Controllers.Book.BookListController.PostBookList (DocumentStorageAPI)' has more than one parameter that was specified or inferred as bound from request body. Only one parameter per action may be bound from body. Inspect the following parameters, and use 'FromQueryAttribute' to specify bound from query, 'FromRouteAttribute' to specify bound from route, and 'FromBodyAttribute' for parameters to be bound from body: BookList bookList StoreList storeList
How can I get my controller to allow me to add a new bookList and update the needed storeList?
Thanks!
The body of the request should be just one object and the PostBookList
method must have only one parameter (with the [FromBody]
attribute). If you need both classes to use within the method create a new class like this:
public class PostBookListRequest
{
public BookList BookList { get; set; }
public StoreList StoreList { get; set; }
}
change the PostBookList
method to
public async Task<ActionResult<BookList>> PostBookList([FromBody]PostBookListRequest request)
{
// Your logic here
}
And in the BODY of the request do
{
"bookList": {
"bookId": "bc381612-c63b-4438-b35b-161a3a568fc7",
"bookTitle": "Is this a test 2?"
},
"storeList": {
"storeId": "0001f801-6909-4b6e-8652-e1b49745280f",
"bookId": "bc381612-c63b-4438-b35b-161a3a568fc7"
}
}
You can use body like this:
{
"bookId": "bc381612-c63b-4438-b35b-161a3a568fc7",
"title": "Is this a test 2?",
"storeId" "0001f801-6909-4b6e-8652-e1b49745280f"
}
In Controller you need additional class BookListBinding with this 3 fields, which you will use for create you 2 objects, for example.
[HttpPost]
public async Task<ActionResult> PostBookList(BookListBinding binding)
{
var bookList = new BookList
{
Id = binding.BookId,
Title = binding.Title
});
var storeList = new StoreList
{
Id = binding.StoreId,
BookId = binding.BookId
}
// you work with _context
return CreatedAtAction("GetBookList", new { id = binding.BookId }, bookList);
}
Why you need change StoreList? What is it?
You have to create a new model like so-
public class AddBookToStoreModel
{
public Book BookToAdd { get; set; }
public StoreList BookStoreList { get; set; }
}
You have to add the same to the controller definition, like this-
[HttpPost]
public async Task<ActionResult<BookStore>> PostBookList(AddBookToStoreModel model)
Also you need to create the individual Models for Book and StoreList like below-
public class Book
{
public Guid BookId { get; set; }
public string BookTitle { get; set; }
}
public class StoreList
{
public Guid StoreId { get; set; }
public Guid BookId { get; set; }
}
The Json that you post to the controller will look like below-
{
"BookToAdd": {
"bookId": "bc381612-c63b-4438-b35b-161a3a568fc7",
"bookTitle": "Is this a test 2?"
},
"BookStoreList": {
"storeId": "0001f801-6909-4b6e-8652-e1b49745280f",
"bookId": "bc381612-c63b-4438-b35b-161a3a568fc7"
}
}
I hope this works for you.
User contributions licensed under CC BY-SA 3.0