C# 如何压缩HttpWebRequest帖子

C# 如何压缩HttpWebRequest帖子,c#,httpwebrequest,compression,C#,Httpwebrequest,Compression,我正在尝试将数据发布到接受压缩数据的服务器。下面的代码工作正常,但它是未压缩的。我没有使用过压缩或Gzip beofre,因此非常感谢您的帮助 HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest; request.Timeout = 600000; request.Method = verb; // POST request.Accept = "text/xml"; if (!string

我正在尝试将数据发布到接受压缩数据的服务器。下面的代码工作正常,但它是未压缩的。我没有使用过压缩或Gzip beofre,因此非常感谢您的帮助

HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
  request.Timeout = 600000;
  request.Method = verb;  // POST    
  request.Accept = "text/xml";

  if (!string.IsNullOrEmpty(data))
  {
    request.ContentType = "text/xml";        

    byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
    request.ContentLength = byteData.Length;       

    // Here is where I need to compress the above byte array using GZipStream

    using (Stream postStream = request.GetRequestStream())
    {
      postStream.Write(byteData, 0, byteData.Length);         
    }
  }      

  XmlDocument xmlDoc = new XmlDocument();
  HttpWebResponse response = null;
  StreamReader reader = null;
  try
  {
    response = request.GetResponse() as HttpWebResponse;
    reader = new StreamReader(response.GetResponseStream());
    xmlDoc.LoadXml(reader.ReadToEnd());
  }
我是否要gzip整个字节数组?我需要添加其他标题还是删除已经存在的标题

谢谢


-Scott

页面加载事件中:

        Response.AddHeader("Content-Encoding", "gzip");
以及发出压缩请求:


Rick Strahl要回答您提出的问题,发布压缩数据,您只需将请求流包装成gzip流

 using (Stream postStream = request.GetRequestStream())
 {
    using(var zipStream = new GZipStream(postStream, CompressionMode.Compress))
    {
        zipStream.Write(byteData, 0, byteData.Length);         
    }
 }
这与请求gzip响应完全不同,gzip响应更为常见。

试试这种扩展方法。 流将保持打开状态(请参阅GZipStream构造函数)。 压缩完成后,流位置设置为0

public static void GZip(this Stream stream, byte[] data)
{
    using (var zipStream = new GZipStream(stream, CompressionMode.Compress, true))
    {
        zipStream.Write(data, 0, data.Length);
    }
    stream.Position = 0;
}
您可以使用以下测试:

[Test]
public void Test_gzip_data_is_restored_to_the_original_value()
{
    var stream = new MemoryStream();
    var data = new byte[]{1,2,3,4,5,6,7,8,9,10};

    stream.GZip(data);

    var decompressed = new GZipStream(stream, CompressionMode.Decompress);

    var data2 = new byte[10];
    decompressed.Read(data2,0,10);

    Assert.That(data, Is.EqualTo(data2));
}
有关更多信息,请参阅:

我还收到了“在写入所有字节之前无法关闭流”错误,错误代码类似于tnyfst。问题是我有:

request.ContentLength = binData.Length;
其中binData是压缩前的原始数据。显然,压缩内容的长度会有所不同,因此我删除了这一行,并以以下代码结束:

using (GZipStream zipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress))
{
    zipStream.Write(binData, 0, binData.Length);
}

这看起来和我要找的很接近。然而,我得到一个“在写入所有字节之前无法关闭流exc”异常。仍在调查中。Flush()似乎没有帮助。此外,我还需要知道使用什么标题。使用@filipov,这将成为完整答案链接文章解释了如何解压缩响应中返回的数据,而不是如何使用压缩数据构造请求。谢谢,还与fiddler进行了检查,在这种情况下,内容长度似乎是自动写入的