In my View I pass BookViewModel
and I have a form which I am trying to create a Book
with. I can perform this if I use the [FromForm]
attribute but I am trying to understand how that differs from [FromBody]
. Here are my models:
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public int GenreId { get; set; } //foreign key from Genre
public virtual Genre Genre { get; set; }
}
public class BookViewModel
{
public ICollection<Book> Books { get; set; }
public Book Book { get; set; }
}
Here is my View and Controller:
[HttpGet]
public IActionResult Index()
{
BookViewModel books = new BookViewModel
{
Books = _context.Books.Include(x => x.Genre).ToList()
}; // _context.Books is my database context and table
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index([FromForm] BookViewModel b) //works without
{ //[FromForm] too
//code to perform tasks
//etc
//return Json(true); The parameters work fine but I would like [FromBody]
}
View:
<form id="formid" method="post">
<div asp-validation-summary="ModelOnly"></div>
<label>Title</label>
<input asp-for="Book.Title" class="form-control" />
<span asp-validation-for="Book.Title"></span>
<label>Genre</label>
<input asp-for="Book.GenreId" class="form-control" />
<span asp-validation-for="Book.GenreId"></span>
<button type="button" onclick="SaveData()">Submit</button>
</form>
<script>
function SaveData(){
event.preventDefault();
var formData = $("#formid").serialize();
$.ajax({
url: "/",
type: "POST",
data: formData,
beforeSend: function(request){
request.setRequestHeader(
"RequestVerificationToken",
$("[name=__RequestVerificationToken']").val());
}
});
}
</script>
All of this code works fine but I would like to use [FromBody]
instead.
I have added contentType: "application/json"
to my ajax, and added [FromBody]
to my action method, but when I submit my form, BookViewModel
is null in the action method. I would like to know how I could submit my form with [FromBody]
with contentType: "application/json"
instead of application/x-www-url-formencoded
?
[FromBody]
will perform default model binding which is what I want here. I am assuming that the reason [FromBody]
has not worked is because of the way I am serializing the form but I am not sure.
The difference between
[FromForm]
and[FromBody]
as below:[FromForm] : Gets values from posted form fields.
[FromBody] : Gets values from the request body.
To use the
[FromBody]
attribute, you could get the entered value via JQuery, then create JavaScript object, and send it to controller method, code as below:The result as below: