2012-04-12 35 views
9

मेरे पास आईआईएस 7.5 पर होस्ट की गई .NET 3.5 वेबसाइट है।डब्ल्यूसीएफ वेब सेवा में जीजेपी संपीड़न

मेरे पास एक क्लाइंट एप्लिकेशन है जो इस webservice से कनेक्ट होता है।

मैं बदल (क्लाइंट अनुप्रयोग में) 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 में एन्कोड किया गया है (मैं इसे फ़िडलर से देखें), लेकिन कोई अपवाद होती है:

Response is not wellformed XML 

(मुझे लगता है कि ग्राहक जवाब)

डिकोड नहीं है, तो मैं यह पंक्ति निकालना, के रूप में MSDN प्रलेखीकरण

httpWebRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate"); 

जवाब GZip इनकोडिंग नहीं है (और अनुरोध में कोई Accept-Encoding शीर्षलेख है)

+1

आईआईएस के लिए किसी भी सेवा की मेजबानी की संपीड़न समर्थन जोड़ने के लिए एक की सम्भावना होनी चाहिए जोड़ें। कस्टम कोडिंग के माध्यम से GZip संपीड़न को लागू करने का कोई तरीका नहीं है। –

+1

ये .. ठीक है .. और मैं डब्ल्यूसीएफ वेबसाइसेस में जीज़िप संपीड़न का उपयोग कैसे कर सकता हूं? क्योंकि मुझे बहुत सारे टेक्स्ट डेटा स्थानांतरित करना है .. – AndreaCi

+0

मैं लगभग 2-3 साल पहले इस पूरे दर्दनाक प्रक्रिया के माध्यम से चला गया। मुझे मिला समाधान खोजने की कोशिश कर रहे थे, लेकिन अब तक कोई भाग्य नहीं है। इस बीच +1। – leppie

उत्तर

0

हल हो गया !! प्रश्न में कोड सेवा संदर्भों के लिए पर्याप्त था। आप वेब संदर्भों का उपयोग कर रहे हैं, भी लाइन

my_service_object.EnableDecompression = true; 
0

एक संभव तरीका protobuf उपयोग करने के लिए अगर आप दोनों को नियंत्रित WCF सेवा के साथ संपीड़न प्राप्त करने के लिए किया जाएगा ग्राहक और सर्वर।

+0

प्रोटोबफ उन सभी के लिए एक बड़ा दर्द है जो इसका उपयोग कर रहे हैं, बहुत सारे प्रतिबंध यहां हैं। लेकिन किसी भी तरह से आप इसे सार्वजनिक अनुबंध के लिए उपयोग नहीं कर सकते हैं। –

+0

सवाल इंगित करता है कि वे दोनों पक्षों, ग्राहक और सर्वर के नियंत्रण में हैं। क्या आप मुझे "बड़े दर्द" लेख या कुछ सारांश की ओर इंगित कर सकते हैं, मैं बेहतर विचार कर सकता हूं कि समस्याएं क्या हैं? –

+1

सरल एक है यदि आप एक खाली संग्रह भेजते हैं तो आपको एक ही खाली संग्रह के बजाय शून्य मिल जाएगा। –

4

मैंने डाटाकंट्रैक्ट के साथ डब्ल्यूसीएफ का उपयोग करके डेटाटेबल ऑब्जेक्ट्स को स्थानांतरित करने के लिए ऐसा किया है। आप इस प्रकार 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); 
+0

हां, यह वह समाधान है जिसे मैं आगे बढ़ रहा हूं .. लेकिन इसमें कोई समस्या है: स्रोत और गंतव्य ऑब्जेक्ट्स विभिन्न वर्गों के उदाहरण हैं (वेबसाइसेस के लिए अलग-अलग नामस्थानों के कारण) – AndreaCi

+0

मैंने सर्वर के बीच साझा की गई किसी ऑब्जेक्ट परिभाषाओं को रखा है और क्लाइंट एक अलग डीएलएल में और उन्हें मेरे सर्वर और क्लाइंट पक्ष दोनों से संदर्भित किया। इस तरह आपको केवल एक ही स्थान पर इसे परिभाषित/बनाए रखना होगा और आपकी परिभाषाएं सार्वभौमिक हैं। – MrWuf

संबंधित मुद्दे