RestSharp替换弃用SaveAs方法后,下载文件返回Null无数据写入
问题根因
- 新版RestSharp的请求实例不可复用:你先通过同一个request对象执行了
Execute<T>做响应校验,这个操作执行完成后,request实例的内部上下文已经被标记为已消费,后续再对这个实例赋值ResponseWriter、发起下载调用时,RestSharp请求管道不会正常触发完整的下载流程,直接返回null。 - 自定义流处理和内置下载方法逻辑冲突:
DownloadData方法的内部实现已经接管了响应流,会直接把流内容读取为byte数组返回,你手动给request赋值的自定义ResponseWriter根本不会被触发。同时你提前打开的文件写流没有做强制Flush,哪怕有流数据写入,也会卡在内存缓冲区,不会落到临时文件里。
可落地的修复方案
- 拆分两次接口调用的request实例,校验请求、下载请求分别独立构造,绝对不要复用同一个request对象执行多次接口调用。
- 不要手动绑定自定义ResponseWriter,直接使用RestSharp内置的文件下载能力完成流到文件的写入,不需要自己提前打开临时文件流。
- 修正后的可运行参考代码:
var tempFile = Path.GetTempFileName(); var client = new RestClient("https://provider-api.spotify.com/v1/analytics"); // 构造独立的校验请求 var checkRequest = new RestRequest("{licensor}/enhanced/tracks/{year}/{month}/{day}", Method.GET); checkRequest.AddHeader("Authorization", $@"Bearer {token}"); checkRequest.AddUrlSegment("licensor", "licensor_name"); checkRequest.AddUrlSegment("year", 2021); checkRequest.AddUrlSegment("month", 1); checkRequest.AddUrlSegment("day", 10); var checkResponse = client.Execute<SpotifyTracksResourceModel>(checkRequest); if (string.IsNullOrEmpty(checkResponse.Content)) { Console.WriteLine("No data"); return; } // 构造独立的下载请求,不复用校验请求的实例 var downloadRequest = new RestRequest("{licensor}/enhanced/tracks/{year}/{month}/{day}", Method.GET); downloadRequest.AddHeader("Authorization", $@"Bearer {token}"); downloadRequest.AddUrlSegment("licensor", "licensor_name"); downloadRequest.AddUrlSegment("year", 2021); downloadRequest.AddUrlSegment("month", 1); downloadRequest.AddUrlSegment("day", 10); // 直接调用内置下载方法,自动完成流到临时文件的写入 client.DownloadFile(downloadRequest, tempFile);
容易踩的细节坑
- 不要为了省代码复用同一个request实例做多次接口调用,新版RestSharp对请求实例的状态做了生命周期管理,执行一次后实例不会被重置,第二次调用直接走空逻辑。
- 如果需要自定义流处理逻辑,就不要用
DownloadData这类内置的快捷方法,直接调用通用的Execute方法拿到响应流后自行处理,避免不同方法之间的流接管逻辑冲突。 - 手动操作文件流时,必须在写入完成后显式调用
Flush方法,否则数据会滞留在内存缓冲区,出现文件写入为空的假象。
内容的提问来源于stack exchange,提问作者David D.
相关产品推荐
相关产品推荐

