我有一个托管在 IIS7.5 上的 .NET 3.5 Web 服务。
我有一个连接到此网络服务的客户端应用程序。
我(在客户端应用程序中)更改了 httpWebRequest.Create 方法来为 GZip 添加自动解压缩,但它不起作用
WebRequest IWebRequestCreate.Create(Uri uri)
{
HttpWebRequest httpWebRequest =
Activator.CreateInstance(
typeof(HttpWebRequest),
BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { uri, null },
null) as HttpWebRequest;
if (httpWebRequest == null)
return null;
httpWebRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
return httpWebRequest;
}
这样请求是正确发送的,应答是用gzip编码的(我是从Fiddler上看到的),但是出现了异常:
Response is not wellformed XML
(我认为客户没有解码答案)
如果我删除这一行,如 MSDN 文档中所述
httpWebRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
答案不是 GZip 编码的(并且在请求中没有 ACCEPT-ENCODING header )
最佳答案
我这样做是为了使用带有 DataContract 的 WCF 来传输 DataTable 对象。您必须按如下方式创建 DataContract:
[DataContract]
public class WCFDataTableContract
{
[DataMember]
public byte[] Schema { get; set; }
[DataMember]
public byte[] Data { get; set; }
}
然后我创建了一个二进制转换器,它会自动将任何对象转换为字节数组,然后我可以使用 GZip 对其进行压缩。
public static class CompressedBinaryConverter
{
/// <summary>
/// Converts any object into a byte array and then compresses it
/// </summary>
/// <param name="o">The object to convert</param>
/// <returns>A compressed byte array that was the object</returns>
public static byte[] ToByteArray(object o)
{
if (o == null)
return new byte[0];
using (MemoryStream outStream = new MemoryStream())
{
using (GZipStream zipStream = new GZipStream(outStream, CompressionMode.Compress))
{
using (MemoryStream stream = new MemoryStream())
{
new BinaryFormatter().Serialize(stream, o);
stream.Position = 0;
stream.CopyTo(zipStream);
zipStream.Close();
return outStream.ToArray();
}
}
}
}
/// <summary>
/// Converts a byte array back into an object and uncompresses it
/// </summary>
/// <param name="byteArray">Compressed byte array to convert</param>
/// <returns>The object that was in the byte array</returns>
public static object ToObject(byte[] byteArray)
{
if (byteArray.Length == 0)
return null;
using (MemoryStream decomStream = new MemoryStream(byteArray), ms = new MemoryStream())
{
using (GZipStream hgs = new GZipStream(decomStream, CompressionMode.Decompress))
{
hgs.CopyTo(ms);
decomStream.Close();
hgs.Close();
ms.Position = 0;
return new BinaryFormatter().Deserialize(ms);
}
}
}
}
将其转储到您的项目中并在您的服务中这样调用以进行压缩:
dt.Data = CompressedBinaryConverter.ToByteArray(data);
然后在你的客户端像这样调用它来转换回一个对象:
dt = (DataTable)CompressedBinaryConverter.ToObject(wdt.Data);
关于c# - WCF WebService 中的 GZip 压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10125748/