Ajax POST 适用于 [FromForm] 但不适用于 [FromBody]
Ajax POST works with [FromForm] but not with [FromBody]
在我看来,我传递了 BookViewModel
并且我有一个表单,我正试图用它来创建 Book
。如果我使用 [FromForm]
属性,我可以执行此操作,但我试图了解它与 [FromBody]
有何不同。这是我的模型:
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; }
}
这是我的视图和控制器:
[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]
}
查看:
<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>
所有这些代码都可以正常工作,但我想改用 [FromBody]
。
我已将 contentType: "application/json"
添加到我的 ajax,并将 [FromBody]
添加到我的操作方法,但是当我提交表单时,操作中的 BookViewModel
为空方法。我想知道如何使用 [FromBody]
和 contentType: "application/json"
而不是 application/x-www-url-formencoded
?
提交我的表单
[FromBody]
将执行默认模型绑定,这正是我在这里想要的。我假设 [FromBody]
不起作用的原因是因为我序列化表单的方式,但我不确定。
[FromForm]
和[FromBody]
的区别如下:
[FromForm] : 从发布的表单字段中获取值。
[FromBody] : 从请求体中获取值。
要使用[FromBody]
属性,可以通过JQuery获取输入的值,然后创建JavaScript对象,并将其发送给控制器方法,代码如下:
<script>
function SaveData() {
event.preventDefault();
//var formData = $("#formid").serialize();
var bookvm = {};
var book = {};
book.Title = "hello"; //use jquery to get the entered value
book.GenreId = "1001";
var genre = {};
genre.Id = 1001;
genre.Name = "Type A";
book.Genre = genre;
bookvm.Book = book;
$.ajax({
url: "/Home/BookIndex", //change the url to yours
type: "POST",
data: JSON.stringify(bookvm),
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend: function (request) {
request.setRequestHeader(
"RequestVerificationToken",
$("[name='__RequestVerificationToken']").val());
}
});
}
</script>
结果如下:
在我看来,我传递了 BookViewModel
并且我有一个表单,我正试图用它来创建 Book
。如果我使用 [FromForm]
属性,我可以执行此操作,但我试图了解它与 [FromBody]
有何不同。这是我的模型:
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; }
}
这是我的视图和控制器:
[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]
}
查看:
<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>
所有这些代码都可以正常工作,但我想改用 [FromBody]
。
我已将 contentType: "application/json"
添加到我的 ajax,并将 [FromBody]
添加到我的操作方法,但是当我提交表单时,操作中的 BookViewModel
为空方法。我想知道如何使用 [FromBody]
和 contentType: "application/json"
而不是 application/x-www-url-formencoded
?
[FromBody]
将执行默认模型绑定,这正是我在这里想要的。我假设 [FromBody]
不起作用的原因是因为我序列化表单的方式,但我不确定。
[FromForm]
和[FromBody]
的区别如下:
[FromForm] : 从发布的表单字段中获取值。
[FromBody] : 从请求体中获取值。
要使用[FromBody]
属性,可以通过JQuery获取输入的值,然后创建JavaScript对象,并将其发送给控制器方法,代码如下:
<script>
function SaveData() {
event.preventDefault();
//var formData = $("#formid").serialize();
var bookvm = {};
var book = {};
book.Title = "hello"; //use jquery to get the entered value
book.GenreId = "1001";
var genre = {};
genre.Id = 1001;
genre.Name = "Type A";
book.Genre = genre;
bookvm.Book = book;
$.ajax({
url: "/Home/BookIndex", //change the url to yours
type: "POST",
data: JSON.stringify(bookvm),
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend: function (request) {
request.setRequestHeader(
"RequestVerificationToken",
$("[name='__RequestVerificationToken']").val());
}
});
}
</script>
结果如下: