使用C#构造multipart/form-data请求实现Salesforce文档上传问题
核心问题汇总
- 二进制内容传输方式错误
PostBlobAsync2/3中使用StringContent传递文件内容,无论传入的是base64字符串还是原始二进制转的字符串,StringContent都会默认对内容做UTF-8编码,直接破坏PDF等二进制文件的结构。必须使用ByteArrayContent传递原始二进制字节流,Salesforce接收的是原始二进制内容,不需要提前转base64编码。 - 表单字段名配置缺失/错误
第一个版本PostBlobAsync中的JSON部分没有设置Content-Disposition的name属性,既不是entity_content也不是entity_document,Salesforce无法识别传入的JSON对应的业务字段。 - 文件字节被截断
PostBlobAsync中构造ByteArrayContent时使用了pdfBase64.Length - 1,直接砍掉了文件的最后一个字节,导致文件损坏,直接传入完整字节长度即可。 - 手动构造请求的语法错误
PostBlobAsync4中用单引号包裹name和filename的属性值,Salesforce API要求使用双引号;且请求开头多了多余的\r\n,会导致边界识别错误;JSON序列化使用ASCII编码,遇到中文等特殊字符会直接乱码。
正确实现示例
上传ContentVersion版本
public async Task<HttpResponseMessage> UploadContentVersionAsync(string url, string token, string contentDocumentId, byte[] fileBytes, string fileName) { using var httpContent = new MultipartFormDataContent("boundary_string"); // 构造元数据JSON部分 var jsonObj = new { ContentDocumentId = contentDocumentId, ReasonForChange = "业务文档更新", PathOnClient = fileName }; var jsonContent = new StringContent(JsonConvert.SerializeObject(jsonObj), Encoding.UTF8, "application/json"); jsonContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") { Name = "entity_content" }; httpContent.Add(jsonContent); // 构造二进制文件部分 var fileContent = new ByteArrayContent(fileBytes); fileContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/octet-stream"); fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") { Name = "VersionData", FileName = fileName }; httpContent.Add(fileContent); // 发送请求 _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); var response = await _httpClient.PostAsync(url, httpContent); // 出错时优先读取Salesforce返回的具体错误信息,方便快速定位 if (!response.IsSuccessStatusCode) { var errorMsg = await response.Content.ReadAsStringAsync(); _logger.LogError("上传失败,错误详情:{Error}", errorMsg); throw new Exception(errorMsg); } return response; }
上传Document文档
只需要修改JSON对应的字段名和文件字段名即可:
- JSON部分的
Content-Disposition.Name改为entity_document,调整JSON内的业务字段(FolderId、Name等) - 文件部分的
Content-Disposition.Name改为Body
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

