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

如何通过Ajax调用向接收System.IO Stream的C# REST API上传文件

解决Ajax传递文件流到接收Stream参数的C# REST API问题

我有一个接收System.IO.Stream对象作为参数的C# REST API方法,尝试用Ajax通过FormData或File对象传递文件流但遇到问题,以下是可行的解决方案:


原代码问题梳理

原C# API方法

[WebInvoke(UriTemplate = "/{businessObjectId}/uploadAttachment?filename={filename}&caption={caption}", Method = "POST", RequestFormat = WebMessageFormat.Raw)]
public Message UploadAttachment(string filename, string caption, Stream stream, string businessObjectId)
{
    // 原有业务逻辑
}

注:原代码缺少Method = "POST"和RequestFormat = WebMessageFormat.Raw配置,这两个参数是API正确接收原始二进制流的关键

原Ajax代码问题

  • File对象初始化错误:new File(fileData[0].files, fileName, ...) 无需重新创建File,直接使用fileData[0].files[0]即可
  • URL未编码:文件名、caption含特殊字符时会导致请求失败
  • 已废弃的live方法:应替换为on方法

方案一:直接传递文件原始流(匹配API的Stream参数)

这种方式直接将文件二进制流发送给API,适合API明确接收Stream的场景

修改后的Ajax代码

$("input[name*='btnUpload']").on("click", function () {
    addGlobalAttachment();
});

function addGlobalAttachment() {
    var fileInput = $("input[id*='fileUpload']")[0];
    if (!fileInput.files || fileInput.files.length === 0) {
        alert("请选择要上传的文件");
        return;
    }
    
    var file = fileInput.files[0];
    var fileName = encodeURIComponent(file.name);
    var fileCaption = encodeURIComponent($("input[name*='txtFileCaption']").val());
    var friendlyID = $(".order").html().trim();
    
    var URL = `http://localhost:62059/Order/${friendlyID}/uploadAttachment?filename=${fileName}&caption=${fileCaption}`;
    
    $.ajax({
        type: 'POST',
        url: URL,
        data: file,
        processData: false,
        contentType: file.type || 'application/octet-stream',
        success: function (attachmentResult) {
            console.log("上传成功", attachmentResult);
        },
        error: function (xhr, status, error) {
            console.error("上传失败", error);
        }
    });
}

方案二:使用FormData传递(更灵活,支持多参数/多文件)

如果需要同时传递更多参数或后续扩展多文件上传,推荐使用FormData

修改后的Ajax代码

$("input[name*='btnUpload']").on("click", function () {
    addGlobalAttachment();
});

function addGlobalAttachment() {
    var fileInput = $("input[id*='fileUpload']")[0];
    if (!fileInput.files || fileInput.files.length === 0) {
        alert("请选择要上传的文件");
        return;
    }
    
    var file = fileInput.files[0];
    var fileCaption = $("input[name*='txtFileCaption']").val();
    var friendlyID = $(".order").html().trim();
    
    var formData = new FormData();
    formData.append("file", file);
    formData.append("filename", file.name);
    formData.append("caption", fileCaption);
    formData.append("businessObjectId", friendlyID);
    
    var URL = "http://localhost:62059/Order/uploadAttachment";
    
    $.ajax({
        type: 'POST',
        url: URL,
        data: formData,
        processData: false,
        contentType: false,
        success: function (attachmentResult) {
            console.log("上传成功", attachmentResult);
        },
        error: function (xhr, status, error) {
            console.error("上传失败", error);
        }
    });
}

对应的API修改

[WebInvoke(UriTemplate = "/uploadAttachment", Method = "POST")]
public Message UploadAttachment()
{
    var httpRequest = HttpContext.Current.Request;
    string filename = httpRequest.Form["filename"];
    string caption = httpRequest.Form["caption"];
    string businessObjectId = httpRequest.Form["businessObjectId"];
    
    Stream stream = httpRequest.Files["file"].InputStream;
    
    // 原有业务逻辑处理
}

常见问题排查

  • 跨域问题:若前后端不在同一域名,需在API端配置CORS,允许Content-Type等请求头及POST方法
  • 上传大小限制:需在API配置中调整最大上传文件大小(如web.config的maxRequestLength或maxAllowedContentLength)
  • jQuery版本:建议使用3.x以上版本,确保对File对象和FormData的支持

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:31:01