2010-11-11 27 views
13

Tôi đang cố đăng dữ liệu lên máy chủ chấp nhận dữ liệu đã nén. Mã dưới đây hoạt động tốt, nhưng nó không nén. Tôi đã không làm việc với nén hoặc Gzip beofre, vì vậy bất kỳ trợ giúp là appriciated.Cách nén một Bài đăng HttpWebRequest

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()); 
    } 

Tôi có gzip toàn bộ mảng byte không? Tôi có cần phải thêm các tiêu đề khác hoặc xóa tiêu đề đã có ở đó không?

Cảm ơn!

-Scott

Trả lời

3

Trong Page_Load sự kiện:

 Response.AddHeader("Content-Encoding", "gzip"); 

Và để làm yêu cầu nén:

HttpWebRequest and GZip Http Responses bởi Rick Strahl

+4

Bài viết được liên kết giải thích cách giải nén dữ liệu được trả về, nhưng không phải cách cấu trúc yêu cầu sử dụng dữ liệu nén. – Scott

+0

@Scott Đã cập nhật. –

12

Để trả lời những câu hỏi mà bạn hỏi, để POST dữ liệu nén, tất cả những gì bạn cần làm là gói luồng yêu cầu bằng gzip stre am

using (Stream postStream = request.GetRequestStream()) 
{ 
    using(var zipStream = new GZipStream(postStream, CompressionMode.Compress)) 
    { 
     zipStream.Write(byteData, 0, byteData.Length);   
    } 
} 

Điều này hoàn toàn khác so với yêu cầu phản hồi gzip, điều phổ biến hơn nhiều.

+3

Điều này trông khá gần với những gì tôi đang tìm kiếm. Tuy nhiên, tôi nhận được một "không thể đóng dòng exc cho đến khi tất cả các byte được viết" ngoại lệ. Vẫn đang điều tra điều đó. Flush() dường như không giúp được gì. Ngoài ra, tôi stil cần phải biết những gì tiêu đề để sử dụng cho việc này. – Scott

+0

với @filipov [answer] (http://stackoverflow.com/a/23055905/492258) điều này trở thành câu trả lời hoàn chỉnh –

0

Thử phương pháp tiện ích mở rộng này. Luồng sẽ được mở ra (xem hàm tạo GZipStream). Vị trí dòng được đặt thành 0 sau khi quá trình nén hoàn tất.

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; 
} 

Bạn có thể sử dụng thử nghiệm sau đây:

[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)); 
} 

Để biết thêm thông tin xem: http://msdn.microsoft.com/en-us/library/hh158301(v=vs.110).aspx

3

Tôi cũng nhận được "Can dòng không chặt chẽ cho đến khi tất cả các byte được viết" lỗi sử dụng mã tương tự của tnyfst. Vấn đề là tôi đã có:

request.ContentLength = binData.Length; 

trong đó binData là dữ liệu thô của tôi trước khi nén. Rõ ràng độ dài của nội dung nén sẽ khác nhau, vì vậy tôi vừa xóa dòng này và kết thúc bằng mã này:

using (GZipStream zipStream = new GZipStream(request.GetRequestStream(), CompressionMode.Compress)) 
{ 
    zipStream.Write(binData, 0, binData.Length); 
} 
Các vấn đề liên quan