9

IIS7.5でホストされている.NET3.5Webサービスがあります。

このWebサービスに接続するクライアントアプリケーションがあります。

(クライアントアプリケーションで)httpWebRequest.Createメソッドを変更してGZipのautomaticDecompressionを追加しましたが、機能しません

 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ヘッダーがありません)

4

3 に答える 3

4

DataContractでWCFを使用してDataTableオブジェクトを転送するためにこれを行いました。次のように DataContract を作成する必要があります。

[DataContract]
public class WCFDataTableContract
{
    [DataMember]
    public byte[] Schema { get; set; }

    [DataMember]
    public byte[] Data { get; set; }
}

次に、GZip を使用して圧縮できるバイト配列に任意のオブジェクトを自動的に変換する Binary Converter を作成しました。

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);
于 2012-04-18T13:28:41.820 に答える
0

考えられる1つの方法は、クライアントとサーバーの両方を制御する場合に、protobufを使用してWCFサービスで圧縮を実現することです。

于 2012-04-13T05:54:44.690 に答える
0

解決しました!! 問題のコードは、サービスの参照には十分でした。Web 参照を使用している場合は、次の行も追加します

my_service_object.EnableDecompression = true;
于 2013-10-09T09:40:23.553 に答える