You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET中使用Fetch向Controller传参无接收问题排查

问题:Fetch发送JSON数据到ASP.NET Controller无法接收数据

我通过卡片输入框收集数据,用Fetch API发送到ASP.NET的Controller,但Controller始终无法获取到数据。浏览器DevTools里能看到请求携带了数据,但调试Controller时,接收的参数是空的。相关代码如下:

script.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.log("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();
  });
});

View

@model CardList

<!DOCTYPE html>
<html lang="en">

<head>
    <script src="~/js/script.js">
    </script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/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>

Models

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; }
}

Controller

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 });
    }
}

解决方案

1. 修改Controller的参数绑定方式

你用[FromForm]标记参数,但Fetch发送的是JSON格式数据,ASP.NET无法自动将JSON绑定到FromForm参数。把[FromForm]改成[FromBody]:

[HttpPost]
[Route("Cards/Create/")]
public IActionResult Create([FromBody] CardList list)

2. 调整前端发送的数据结构

你的CardList类包含Cards属性,但前端直接发送了数组,没有包装在Cards字段里。修改saveCardDataToServer函数中的body部分:

body: JSON.stringify({ Cards: cards })

3. 阻止表单默认提交行为

表单提交时会触发默认的POST请求,和你的Fetch请求冲突,导致数据无法正确接收。在submit事件中添加event.preventDefault():

document.querySelector('form.cards').addEventListener('submit', function(event) {
    event.preventDefault(); // 阻止默认表单提交
    saveCardDataToServer();
});

4. 修复Controller中的循环变量错误

Controller里的foreach循环遍历的是未定义的cards变量,应该改成list.Cards,同时要判断list.Cards不为null:

if (list != null && list.Cards != null)
{
    foreach (var card in list.Cards)
    {
        if (!string.IsNullOrWhiteSpace(card.Term) && !string.IsNullOrWhiteSpace(card.Definition))
        {
            CardsRepository.AddCard(card);
        }
    }
}

5. 初始化CardList的Cards属性

为避免list.Cards为null,在CardList类中初始化属性:

public class CardList
{
    public List<Card> Cards { get; set; } = new List<Card>();
}

完成以上修改后,Controller就能正确接收到Fetch发送的卡片数据了。


内容的提问来源于stack exchange,提问作者Egor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 22:57:04