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

如何不使用FormData,通过JavaScript模型传递HttpPostedFileBase类型参数

核心问题原因

你当前代码拿不到Documents参数是必然的:JSON 协议本身不支持序列化二进制类型,浏览器中的File对象属于二进制数据,JSON.stringify()处理时会直接转为空对象{},后端自然无法完成模型绑定。

你的两个疑问解答

  1. 完全不使用FormData传文件是可以实现的,需要将文件转成Base64字符串后再纳入JS模型传递,适合小文件场景。
  2. 不需要给每个类都单独写HttpPostedFileBase属性,要么转Base64后把文件字段改成字符串数组,要么用基类封装公共文件属性继承即可。

方案1:无FormData、Base64传文件(适配JS模型传递需求)

适合小文件场景,完全符合你想要的JS模型传参逻辑,不需要调整请求头为form-data。

修改步骤

  1. 调整C#模型,将文件接收字段改为字符串数组:
public class ArtGallery
{
    // 注意public首字母要小写,你原代码的Public是语法错误
    public string GallerName { get; set; }
    // 存储文件的Base64字符串
    public string[] Documents { get; set; }
}
  1. 调整JS代码,先将文件转成Base64再塞入模型:
class ArtGallery{
    GallerName;
    Documents = []; // 必须初始化数组,否则push会报错
}

function saveFormData(){
    let gallery = new ArtGallery();
    gallery.GallerName = "Test";
    // 统计待处理文件总数,确保所有文件转码完成后再提交
    let totalFiles = $("input[type=file]").map((i, obj) => obj.files.length).get().reduce((a, b) => a + b, 0);
    let processedCount = 0;

    $.each($("input[type=file]"), function (i, obj) {
        $.each(obj.files, function (j, file) {
            const reader = new FileReader();
            reader.onload = function(e) {
                // 转码完成后将Base64字符串塞入模型
                gallery.Documents.push(e.target.result);
                processedCount++;
                if (processedCount === totalFiles) {
                    saveToDb(gallery);
                }
            }
            reader.readAsDataURL(file);
        });
    });
}

function saveToDb(gallery) {
    // 注意URL要和控制器动作名对应,你原动作是PostUserData,不是PostData
    const url = "/MyController/PostUserData/";
    $.ajax({
        url: url,
        type: 'POST',
        async: true, // 不要用async:false,同步请求会阻塞页面,已被主流浏览器弃用
        data: JSON.stringify({ gallery: gallery }),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (result) {
            // 业务逻辑
        },
        error: function (request) {
            // 异常处理
        }
    });
}
  1. 后端处理Base64字符串转文件:
[HttpPost]
public JsonResult PostUserData(ArtGallery gallery) 
{
    foreach (var base64File in gallery.Documents)
    {
        // 移除Base64前缀(如data:image/png;base64,)
        var pureBase64 = base64File.Split(',')[1];
        byte[] fileBytes = Convert.FromBase64String(pureBase64);
        // 后续按需存本地、存OSS等处理
    }
    // 其余业务逻辑
}

该方案缺点:Base64编码后体积比原文件大33%左右,大文件上传会增加带宽消耗、延长上传时间,不适合10M以上的文件传输。


方案2:FormData通用封装(适合大文件场景)

如果需要传大文件,还是推荐用FormData,只需封装一层通用的模型转FormData逻辑,不需要每个接口重复写代码,同时不需要修改原有C#模型:

通用封装+调用示例

// 通用函数:任意JS模型转FormData
function modelToFormData(model) {
    const formData = new FormData();
    for (const key in model) {
        const value = model[key];
        // 数组类型处理
        if (Array.isArray(value)) {
            for (let i = 0; i < value.length; i++) {
                formData.append(`${key}[${i}]`, value[i]);
            }
            continue;
        }
        formData.append(key, value);
    }
    return formData;
}

// 调用时只需改saveToDb方法即可
function saveToDb(gallery) {
    const url = "/MyController/PostUserData/";
    const formData = modelToFormData(gallery);
    $.ajax({
        url: url,
        type: 'POST',
        processData: false, // 必须配置,禁止jQuery处理FormData
        contentType: false, // 必须配置,禁止jQuery自动设置请求头
        data: formData,
        success: function (result) {
            // 业务逻辑
        },
        error: function (request) {
            // 异常处理
        }
    });
}

解决10个类重复写HttpPostedFileBase的问题

只需封装公共基类,所有需要传文件的类继承即可,不用重复写属性:

// 公共基类
public class BaseFileUploadModel
{
    public HttpPostedFileBase[] Documents { get; set; }
}

// 业务类继承基类即可,不用重复写Documents
public class ArtGallery : BaseFileUploadModel
{
    public string GallerName { get; set; }
}
// 其余9个需要传文件的类同理继承BaseFileUploadModel

其他注意事项

  • C#语法中访问修饰符public首字母为小写,你原代码中写的Public会编译报错,也会导致模型绑定失败
  • 不要使用async: false配置,同步AJAX会阻塞整个页面交互,W3C已经在标准中废弃同步XMLHttpRequest的使用
  • AJAX请求的URL要和后端控制器动作名一致,你原代码中控制器动作是PostUserData,请求URL写的PostData会返回404错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:24:02