Я хочу передать данные со входов карт. Я передаю данные с помощью fetch
в контроллер, а в контроллере нет данных.
скрипт.js
var currentCardNumber = 1;
function addCard() {
currentCardNumber++;
let newCardHTML = `
<div class = "header d-flex justify-content-between p-3">
<h4 class = "card-counter">${currentCardNumber}</h4>
</div>
<div class = "card-body row">
<div class = "term col">
<h3>Term</h3>
<input class = "form-control w-100" name = "term" >
</div>
<div class = "definition col">
<h3>Definition </h3>
<input class = "form-control w-100" name = "definition" >
</div>
</div>
</div> `;
let newCard = document.createElement('div');
newCard.classList.add('card');
newCard.classList.add('mt-3');
newCard.innerHTML = newCardHTML;
let addNewCard = document.querySelector('.cards');
let referenceNode = document.getElementById('create-cards');
addNewCard.insertBefore(newCard, referenceNode);
}
function saveCardDataToServer() {
let cards = [];
document.querySelectorAll('.card').forEach((card) => {
let term = card.querySelector('input[name = "term"]').value.trim();
let definition = card.querySelector('input[name = "definition"]').value.trim();
if (term && definition) {
cards.push({
Term: term,
Definition: definition
});
}
})
fetch('/Cards/Create/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(cards)
})
.then(response => response.json())
.then((data => {
if (data.success) {
console.info("Data successfully saved: ", data);
window.location.href = "/Cards/Learning";
} else {
console.error("Error saving card: ", data.message);
}
}))
}
document.addEventListener('DOMContentLoaded', function() {
let newCard = document.querySelector('.new-card');
newCard.addEventListener('click', function() {
addCard();
});
document.querySelector('form.cards').addEventListener('submit', function() {
saveCardDataToServer();
});
});
Вид
@model CardList
<!DOCTYPE html>
<html lang = "en">
<head>
<script src = "~/js/script.js">
</script>
<link href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel = "stylesheet"
integrity = "sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin = "anonymous" asp-append-version = "true">
</head>
<body>
<main class = "main">
<div class = "container">
<div class = "new-module d-flex justify-content-between mt-5">
<h1>Create new module</h1>
<a class = "btn btn-primary" asp-controller = "Cards" asp-action = "learning" type = "submit">Создать</a>
</div>
<div class = "card mt-5 p-2 pb-3">
<h3>Title</h3>
<input class = "form-control w-100" placeholder = "Enter a name">
</div>
<form asp-controller = "Cards" asp-action = "Create" method = "post" class = "cards">
<div class = "card mt-6" id = "card">
<div class = "header d-flex justify-content-between p-3">
<h4 class = "card-counter">1</h4>
</div>
<div class = "card-body row">
<div class = "term col">
<h3>Term</h3>
<input class = "form-control w-100" name = "term" >
</div>
<div class = "definition col">
<h3>Definition </h3>
<input class = "form-control w-100" name = "definition" >
</div>
</div>
</div>
<input type = "submit" value = "Create" id = "create-cards" class = "btn btn-primary mt-2"/>
</form>
<button class = "new-card w-100 d-flex justify-content-center align-items-center mt-4 mt-s rounded-2" style = "height: 5rem" type = "button">
<h3>+ Add card</h3>
</button>
</div>
</main>
</body>
</html>
Модели
public class Card
{
public int CardId { get; set; }
[Required]
public string Term { get; set; } = string.Empty;
public string Definition { get; set; } = string.Empty;
}
public class CardList
{
public List<Card> Cards { get; set; }
}
Контроллер
public class CardsController : Controller
{
public IActionResult Learning()
{
var cards = CardsRepository.GetCards();
return View(cards);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
[Route("Cards/Create/")]
public IActionResult Create([FromForm] CardList list)
{
if (list != null)
{
foreach (var card in cards)
{
if (!string.IsNullOrWhiteSpace(card.Term) && !string.IsNullOrWhiteSpace(card.Definition))
{
CardsRepository.AddCard(card);
}
}
return Json(new { success = true, message = "Card saved successfully " });
}
var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage);
return Json(new { success = false, message = "Validation error", errors = errors });
}
}
Я вижу данные в DevTools после выборки, однако не вижу данных в контроллере через отладчик.
измените [FromForm] на [FromBody] в методе вашего контроллера:
public IActionResult Create (список [FromBody] CardList)
Я хочу передавать данные со входов карт. Я передаю данные с помощью выборки в контроллер, и в контроллере нет данных.
Судя по вашему общему коду и описанию, ваша проблема связана с методом привязки данных в контроллере.
Атрибут FromForm ожидает данные в кодировке формы, но вы отправляете данные JSON из запроса на выборку. Чтобы справиться с этим правильно, вам следует либо изменить код на стороне клиента, чтобы он мог обрабатывать [FromForm]
привязку данных, либо изменить атрибут на FromBody, чтобы позволить контроллеру правильно анализировать входящую полезную нагрузку JSON.
Я бы посоветовал вам использовать FromBody в контроллере, чтобы вам требовалось минимальное изменение или модификация, поскольку ваш клиентский код в настоящее время предназначен для взаимодействия с данными FromBody Jason.
Для этого измените следующий код:
function saveCardDataToServer() {
let cards = [];
document.querySelectorAll('.card').forEach((card) => {
let termInput = card.querySelector('input[name = "term"]');
let definitionInput = card.querySelector('input[name = "definition"]');
if (termInput && definitionInput) {
let term = termInput.value.trim();
let definition = definitionInput.value.trim();
if (term && definition) {
cards.push({
Term: term,
Definition: definition
});
}
} else {
console.error("Input elements not found in card:", card);
}
});
Примечание. Вышеуказанный метод в вашем фрагменте может вызвать сбой, потому что, если какой-либо элемент .card
не содержит входной элемент с именем term
или definition
, querySelector возвращает null
. Строка let term = card.querySelector('input[name = "term"]').value.trim();
вызовет ошибку TypeError, поскольку у null нет свойства value. Поэтому, чтобы это исправить, я изменил это, включив в него проверку (if (termInput && DefinitionInput)) для обеспечения того, чтобы входные элементы были найдены, прежде чем пытаться получить доступ к их свойствам значений.
Изменить тело запроса:
body: JSON.stringify({ Cards: cards })
Контроллер:
public IActionResult Create([FromBody] CardList Cards)
Выход:
Когда я реализую IEnumerable в CardList, я снова получаю ноль в контроллере. Подскажите, пожалуйста, где об этом прочитать?
Эй, спасибо за ваш ответ, вообще-то мне нужно сначала проверить сценарий, было бы неплохо, если бы вы опубликовали для этого новый вопрос; следовательно, я могу провести соответствующее расследование и объяснить, почему это происходит.
Для этого я разместил новый вопрос.
Хорошо, это удобнее и рассматривается индивидуально.
Проверили ли вы трассировку сети браузера, были ли переданы данные?