#c# #asp.net-core #post #frombodyattribute
#c# #asp.net-ядро #Публикация #атрибут frombodyattribute
Вопрос:
На мой взгляд, я прохожу 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]
в свой метод action, но когда я отправляю свою форму, BookViewModel
в методе action значение равно null. Я хотел бы знать, как я мог бы отправить свою форму с [FromBody]
помощью with contentType: "application/json"
вместо application/x-www-url-formencoded
?
[FromBody]
будет выполняться привязка модели по умолчанию, чего я и хочу здесь. Я предполагаю, что причина [FromBody]
не сработала из-за способа сериализации формы, но я не уверен.
Комментарии:
1. «Я добавил ContentType: «application / json» в мой ajax»… это не имеет смысла, потому что вы не отправляете данные JSON
2. То, что вы делаете прямо сейчас, прекрасно и правильно, нет необходимости его менять и не нужно получать никаких преимуществ. Переход на использование JSON потребует создания большого количества избыточного кода на стороне клиента. Вы отправляете данные формы из отправленной формы. Вы используете правильный механизм для этого, так что придерживайтесь его. Используйте правильный инструмент для работы и не усложняйте его
3. Хорошо, я проведу исследование о том, когда я должен использовать json, а не данные формы. Но я думаю, что в этой ситуации это было бы бесполезно.
4. Правильно, это вам здесь не поможет. Это полезно, если вы отправляете из клиента, не являющегося браузером, или если вам нужно отправить очень сложную структуру данных с большим количеством массивов и объектов, например
Ответ №1:
Разница между [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>
Результат, как показано ниже: