.NET Framework4.8下RestSharp+Polly获取序列化请求体并实现Gzip压缩
解决方案
方法一:手动序列化+压缩(最直接可控)
跳过RestSharp自动序列化流程,自己完成对象序列化、Gzip压缩,再将压缩后的内容作为请求体提交,彻底避免内容追加和重试异常问题:
- 序列化请求对象为JSON字符串:
' 假设你的请求数据对象是 requestData Dim serializer As New RestSharp.Serializers.JsonSerializer() serializer.ContentType = "application/json" Dim serializedBody As String = serializer.Serialize(requestData)
- 执行Gzip压缩:
Dim compressedBytes As Byte() Using dataStream As New MemoryStream() Using zipStream As New System.IO.Compression.GZipStream(dataStream, System.IO.Compression.CompressionMode.Compress) Using writer As New StreamWriter(zipStream) writer.Write(serializedBody) End Using End Using compressedBytes = dataStream.ToArray() End Using
- 构建请求并结合Polly重试:
Dim request As New RestRequest(Method.POST) ' 设置请求头 request.AddHeader("Content-Encoding", "gzip") request.AddHeader("Content-Type", "application/json") ' 添加压缩后的请求体 request.AddParameter("application/x-gzip", compressedBytes, ParameterType.RequestBody) ' Polly重试策略示例 Dim retryPolicy = Policy.Handle(Of Exception)().Retry(2) Dim restResponse As IRestResponse = retryPolicy.Execute(Function() client.Post(request))
这种方式完全由你控制序列化和压缩逻辑,每次重试都会重新生成完整的请求内容,不会出现流消耗或内容追加问题。
方法二:拦截RestSharp自动序列化后的内容并替换
如果必须依赖RestSharp自动序列化,可通过OnBeforeRequest拦截原始内容并替换,但需注意重置流位置避免异常:
request.OnBeforeRequest = Async Function(httpRequestMessage) ' 读取原始序列化内容 Dim originalContent As String = Await httpRequestMessage.Content.ReadAsStringAsync() ' 重置流缓存,避免后续读取失败 Await httpRequestMessage.Content.LoadIntoBufferAsync() ' 压缩原始内容 Dim compressedBytes As Byte() Using dataStream As New MemoryStream() Using zipStream As New System.IO.Compression.GZipStream(dataStream, System.IO.Compression.CompressionMode.Compress) Using writer As New StreamWriter(zipStream) writer.Write(originalContent) End Using End Using compressedBytes = dataStream.ToArray() End Using ' 完全替换为压缩后的内容 httpRequestMessage.Content = New ByteArrayContent(compressedBytes) ' 更新请求头 httpRequestMessage.Content.Headers.ContentEncoding.Add("gzip") httpRequestMessage.Content.Headers.ContentType = New System.Net.Http.Headers.MediaTypeHeaderValue("application/json") End Function
核心注意事项
- 必须调用
LoadIntoBufferAsync(),因为ReadAsStringAsync()会消耗流,重置后才能确保重试时流可正常读取。 - Polly重试时会重新触发
OnBeforeRequest,每次都会重新执行压缩逻辑,避免复用已消耗的流导致请求失败。
内容的提问来源于stack exchange,提问作者Lyra Leo
相关产品推荐
相关产品推荐

