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
相关产品推荐
相关产品推荐

