C#(.NET)调用REST API下载Zip文件遇415错误,求解决方案
问题分析
- 错误核心原因:你的
GetJson方法全局设置了Accept: application/zip请求头,导致所有请求(包括获取Token的JSON请求)都携带这个头。虽然Token请求可能侥幸成功,但下载Zip的API端点不接受该Accept头,直接返回415错误。 - 方法设计不匹配:
GetJson是为解析JSON响应设计的,用它处理二进制Zip文件完全不合适,必须用专门的方法处理流下载逻辑。
解决方案
1. 修复GetJson方法的请求头
将GetJson里的Accept头改为application/json,确保JSON请求的正确性:
static dynamic GetJson(string url, string accessToken = null, HttpContent body = null) { using (HttpClient client = new HttpClient()) { // 改为JSON格式的Accept头,适配Token等JSON请求 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); if (accessToken != null) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } HttpResponseMessage response; if (body == null) { response = client.GetAsync(url).Result; } else { response = client.PostAsync(url, body).Result; } if (response.IsSuccessStatusCode) { return response.Content.ReadAsAsync<dynamic>().Result; } else { Console.WriteLine("{0}: {1} ({2})", url, (int)response.StatusCode, response.ReasonPhrase); return null; } } }
2. 添加专门的Zip文件下载方法
创建DownloadZipFile方法,负责获取二进制流并保存到临时目录:
static bool DownloadZipFile(string url, string accessToken, string tempPath) { using (HttpClient client = new HttpClient()) { if (accessToken != null) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } // 可根据Postman的请求头调整,若Postman未设置特殊Accept头,可注释此行 // client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream")); using (HttpResponseMessage response = client.GetAsync(url).Result) { if (!response.IsSuccessStatusCode) { Console.WriteLine("{0}: {1} ({2})", url, (int)response.StatusCode, response.ReasonPhrase); return false; } // 确保临时目录存在 Directory.CreateDirectory(tempPath); // 生成唯一临时文件名 string zipFilePath = Path.Combine(tempPath, $"download_{Guid.NewGuid()}.zip"); // 读取响应流并写入本地文件 using (Stream stream = response.Content.ReadAsStreamAsync().Result) using (FileStream fileStream = new FileStream(zipFilePath, FileMode.Create, FileAccess.Write)) { stream.CopyTo(fileStream); } Console.WriteLine($"Zip文件已保存到: {zipFilePath}"); return true; } } }
3. 修改Main方法调用下载逻辑
替换原来调用GetJson的代码,改用DownloadZipFile:
static void Main(string[] args) { var tokenData = GetJson(tokenUrl, null, body); if (tokenData == null) Environment.Exit(0); string accessToken = tokenData.access_token; string odataUrl = innovatorUrl + "/server/odata/ACT_Document Set('D71DC18B35764C509F3565F511DFFF20')/act_reqtify_project_file/$value"; // 使用系统临时目录,也可自定义路径 string tempDirectory = Path.GetTempPath(); bool downloadSuccess = DownloadZipFile(odataUrl, accessToken, tempDirectory); if (!downloadSuccess) Environment.Exit(1); }
额外注意事项
- 对齐Postman请求头:打开Postman的请求详情,查看
Headers标签下的所有请求头,确保DownloadZipFile里的请求头和Postman完全一致(比如是否存在自定义头)。 - 异步优化:当前代码用
.Result同步调用,生产环境建议改用async/await避免线程阻塞,例如将方法改为异步后,在Main方法中用GetAwaiter().GetResult()执行。
内容的提问来源于stack exchange,提问作者maher kochbati
相关产品推荐
相关产品推荐

