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

C# Xamarin使用RestSharp上传文件到API正常但HttpClient失败

问题原因及修复方案

1. 核心错误:表单参数键值写反

你在MultipartFormDataContent里添加action参数的语句完全颠倒了键和值:
原错误代码:

{ new StringContent("action"), "bp_avatar_upload" }

RestSharp里的正确逻辑是参数名=action,参数值=bp_avatar_upload,对应正确写法应该是:

{ new StringContent("bp_avatar_upload"), "action" }

这是触发「Invalid form submission」报错的直接原因,服务端接收不到正确的action参数,校验不通过。

2. 次要错误:ContentDisposition类型错误

文件的ContentDispositionHeaderValue应该用form-data而不是attachment,attachment是用于下载响应的头,表单上传文件标准用form-data,调整代码:

fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
    Name = "file",
    FileName = Path.GetFileName(data.Path),
};

虽然部分服务端兼容attachment写法,但不符合multipart表单规范,建议修改。

3. 其他优化点(非报错必要,但符合最佳实践)

  • 不要每次请求都实例化新的HttpClient,重复实例化会导致套接字耗尽,建议把HttpClient设为静态全局实例复用
  • 当前User-Agent只有存在authorisationToken时才会添加,和RestSharp的逻辑不一致,建议把User-Agent的设置移到token判断外面,不管是否传token都统一添加
  • MemoryStream使用后记得释放,推荐用using包裹避免内存泄漏

修正后的完整代码示例

// 建议把HttpClient设为静态全局变量,不要每次请求新建
private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler()
{
    ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
});

public async Task<string> PostMediaFile(MediaFile data, string path, bool https = false, string authorisationToken = "")
{
    byte[] fileAsBytes;
    // 用using释放MemoryStream
    using (var memoryStream = new MemoryStream())
    {
        await data.GetStream().CopyToAsync(memoryStream);
        fileAsBytes = memoryStream.ToArray();
    }

    var fileContent = new ByteArrayContent(fileAsBytes);
    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
    {
        Name = "file",
        FileName = Path.GetFileName(data.Path),
    };
    fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");

    var content = new MultipartFormDataContent
    {
        { fileContent, "file", Path.GetFileName(data.Path) },
        // 修正参数顺序:参数值在前,参数名在后
        { new StringContent("bp_avatar_upload"), "action" }
    };

    var requestMethod = https ? "https://" : "http://";
    var serverString = requestMethod + path;

    // 清理之前的请求头,避免复用HttpClient时头冲突
    _httpClient.DefaultRequestHeaders.Clear();
    if (!string.IsNullOrWhiteSpace(authorisationToken))
    {
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authorisationToken);
    }
    // 统一添加User-Agent,和RestSharp逻辑一致
    _httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");

    _httpClient.Timeout = TimeSpan.FromMilliseconds(timeOut);
    using (var response = await _httpClient.PostAsync(serverString, content))
    {
        return await response.Content.ReadAsStringAsync();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 06:06:03