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

基于JavaScript Fetch的.NET MVC参数传递问题

问题

维护一个已升级至.NET 8的C# MVC遗留系统,前端原用jQuery AJAX调用后端接口正常,切换为Fetch API时遇到参数传递问题:

后端接口定义:

public IActionResult SearchCerts(string Company, string ExpStart, string ExpEnd)
{
    // 业务逻辑
    return PartialView("_SearchResults", Results);
}

原AJAX代码:

function SearchCerts() {
    $.ajax({
        url: "/Certs/SearchCerts",
        data: { 
            Company: document.getElementById("edtSearchCompany").value,
            ExpStart: document.getElementById("edtSearchExpires1").value,
            ExpEnd: document.getElementById("edtSearchExpires2").value
        },
        dataType: "html",
        async: true,
        success: function (data) {
            $('#divSearchResults').html(data);
        },
        error: function () {
            alert("Error");
        }
    });
}

使用Fetch API时,尝试用JSON.stringify传递对象,后端接收的参数全为null:

async function SearchCertsExecute() {
    var SendData = {
        Company: document.getElementById("edtSearchCompany").value,
        ExpStart: document.getElementById("edtSearchExpires1").value,
        ExpEnd: document.getElementById("edtSearchExpires2").value
    };

    let Results = await fetch("/Certs/SearchCerts", {
        method: 'POST',
        body: JSON.stringify(SendData)
    });

    if (Results.ok) {
        var data = await Results.text();
        $('#divSearchResults').html(data);
    } else {
        alert("HTTP-Error: " + Results.status);
    }
}

目前仅能通过修改后端接收IFormCollection参数、前端传递FormData的方式实现参数传递,但希望保留原后端接口结构。

原因与解决方法

核心原因

jQuery AJAX默认会把data对象序列化为application/x-www-form-urlencoded格式的表单数据,并自动设置对应的Content-Type请求头,ASP.NET MVC的默认模型绑定可以直接识别这种格式并绑定到单个参数上。

而你用JSON.stringify传递时,存在两个问题:

  1. 没有设置Content-Type: application/json请求头,后端无法识别请求体是JSON格式,仍按表单格式解析,自然拿不到数据。
  2. 即使设置了请求头,ASP.NET MVC默认不会从JSON请求体中绑定单个参数(string Company这类),需要显式配置或封装参数为类。

解决方法一:保持后端接口不变,用表单格式传递(和AJAX行为一致)

将JavaScript对象转为application/x-www-form-urlencoded格式,并设置对应请求头:

async function SearchCertsExecute() {
    const SendData = {
        Company: document.getElementById("edtSearchCompany").value,
        ExpStart: document.getElementById("edtSearchExpires1").value,
        ExpEnd: document.getElementById("edtSearchExpires2").value
    };

    // 转换为urlencoded格式
    const formData = new URLSearchParams(SendData);

    const Results = await fetch("/Certs/SearchCerts", {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: formData
    });

    if (Results.ok) {
        const data = await Results.text();
        $('#divSearchResults').html(data);
    } else {
        alert("HTTP-Error: " + Results.status);
    }
}

这种方式完全匹配原AJAX的请求格式,后端无需任何修改即可正常接收参数。

解决方法二:改用JSON格式传递,调整后端接口

如果希望用JSON格式传递,需要调整后端接口以支持JSON请求体绑定:

步骤1:创建请求DTO类

public class SearchCertsRequest
{
    public string Company { get; set; }
    public string ExpStart { get; set; }
    public string ExpEnd { get; set; }
}

步骤2:修改后端接口,添加[FromBody]特性

public IActionResult SearchCerts([FromBody] SearchCertsRequest request)
{
    // 使用request.Company、request.ExpStart、request.ExpEnd获取参数
    return PartialView("_SearchResults", Results);
}

步骤3:前端Fetch设置正确请求头

async function SearchCertsExecute() {
    const SendData = {
        Company: document.getElementById("edtSearchCompany").value,
        ExpStart: document.getElementById("edtSearchExpires1").value,
        ExpEnd: document.getElementById("edtSearchExpires2").value
    };

    const Results = await fetch("/Certs/SearchCerts", {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(SendData)
    });

    if (Results.ok) {
        const data = await Results.text();
        $('#divSearchResults').html(data);
    } else {
        alert("HTTP-Error: " + Results.status);
    }
}

注意:[FromBody]特性只能在一个参数上使用,因此需要将多个参数封装为一个类对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:24:49