Most webservers will compress data if the clients support it.
Unfortunately for .net developers the auto generated proxy classes that access webservices don’t include this functionality.
I’ll show you how to achieve this while avoiding changing any code in the auto generated proxy classes.
(These classes utilize ICSharpCode.SharpZipLib.dll so you’ll have to download this)
This following class will deal with decompressing a response.
Imports System.Net
Imports ICSharpCode.SharpZipLib
Public Class UncompressedGzipResponse
Inherits System.Net.WebResponse
Private cCompressedGzipResponse As HttpWebResponse
Public Sub New(ByVal compressedGzipResponse As HttpWebResponse)
MyBase.New()
cCompressedGzipResponse = compressedGzipResponse
End Sub
Public Overrides Function GetResponseStream() As System.IO.Stream
Dim compressedStream As System.IO.Stream = New GZip.GZipInputStream(cCompressedGzipResponse.GetResponseStream)
Dim decompressedStream As New System.IO.MemoryStream
Dim size As Integer = 2048
Dim writeData(2048) As Byte
While True
size = compressedStream.Read(writeData, 0, size)
If size > 0 Then
decompressedStream.Write(writeData, 0, size)
Dim s As String = System.Text.Encoding.ASCII.GetString(writeData)
s = s & ""
Else
Exit While
End If
End While
decompressedStream.Seek(0, IO.SeekOrigin.Begin)
Return CType(decompressedStream, IO.Stream)
End Function
Public Overrides Property ContentType() As String
Get
Return cCompressedGzipResponse.ContentType
End Get
Set(ByVal value As String)
cCompressedGzipResponse.ContentType = value
End Set
End Property
Public Overrides Property ContentLength() As Long
Get
Return cCompressedGzipResponse.ContentLength
End Get
Set(ByVal value As Long)
cCompressedGzipResponse.ContentLength = value
End Set
End Property
Public Overrides ReadOnly Property Headers() As System.Net.WebHeaderCollection
Get
Return cCompressedGzipResponse.Headers
End Get
End Property
End Class
This next class will handle most of the logic so that your proxy class can be as small as possible:
Public Class WebServiceCompressionHelper
Public Shared Function GetWebRequest(ByVal uri As System.Uri, ByVal output As WebRequest, ByVal compress As Boolean) As WebRequest
'*** add gzip
If compress Then
output.Headers.Item(Net.HttpRequestHeader.AcceptEncoding) = "gzip"
End If
Return output
End Function
Public Shared Function GetWebResponse(ByVal output As WebResponse, ByVal request As System.Net.WebRequest) As WebResponse
Dim compressedResponse As HttpWebResponse = Nothing
If TypeOf output Is HttpWebResponse Then
compressedResponse = CType(output, HttpWebResponse)
End If
If compressedResponse IsNot Nothing AndAlso compressedResponse.ContentEncoding = "gzip" Then
output = New UncompressedGzipResponse(compressedResponse)
End If
Return output
End Function
End Class
In order to make use of this we need to tap into a few methods in the auto generated proxy. The easiest way to do this is to extend the proxy class into your own subclass, like so:
Public Class MyService
Inherits generated.proxy.class.here
Protected Overrides Function GetWebRequest(ByVal uri As System.Uri) As System.Net.WebRequest
Return Walshgroup.Webservices.Common.WebServiceCompressionHelper.GetWebRequest(uri, MyBase.GetWebRequest(uri), True)
End Function
Protected Overrides Function GetWebResponse(ByVal request As System.Net.WebRequest) As System.Net.WebResponse
Dim output As System.Net.WebResponse = MyBase.GetWebResponse(request)
Return Walshgroup.Webservices.Common.WebServiceCompressionHelper.GetWebResponse(output, request)
End Function
End Class
Now, instead of instantiating your generated proxy class, you will simply instantiate your subclass.
That’s it!