Enhancing .NET Web Services

by Eric Bergman-Terrell



Listing One



protected override WebRequest GetWebRequest(Uri uri)

// Update the request's HTTP headers to specify that

// we can accept compressed (gzipped, deflated) responses

{

  WebRequest request = base.GetWebRequest(uri);

  // If user checked the Compressed Response checkbox

  if (compressResponse)

  {

    request.Headers.Add("Accept-Encoding", "gzip, deflate");

  }

  return request;

}

protected override WebResponse GetWebResponse(WebRequest request)

// If we've requested compressed responses, return a WebResponse

// derivative that's capable of uncompressing it.

{

  WebResponse result;

  // If user checked the Compressed Response checkbox

  if (compressResponse)

  {

    result = new CompressedWebResponse((HttpWebRequest) request);

  }

  else // no compression requested, return stock WebResponse object

  {

    result = base.GetWebResponse(request);

  }

  // Keep track of content length to measure bandwidth savings.

  responseContentLength = result.ContentLength;

  return result;

}



Listing Two



public override Stream GetResponseStream()



// Decompress the web service response and return it in a stream.

{

  Stream result = null;

  // Clean up previously-used BinaryReader and BinaryWriter.

  if (reader != null)

  {

    reader.Close();

    reader = null;

  }

  if (writer != null)

  {

    writer.Close();

    writer = null;

  }

  try

  {

    // Get response.

    HttpWebResponse webResponse = (HttpWebResponse) request.GetResponse();

    Stream inputStream = null;

    bool decompress = true;

    // Get an input stream based on the type of compression, if any.

    if (webResponse.ContentEncoding == "gzip")

    {

      inputStream = new

        GZipInputStream(webResponse.GetResponseStream());

    }

    else if (webResponse.ContentEncoding == "deflate")

    {

      inputStream = new

        InflaterInputStream(webResponse.GetResponseStream());

    }

    else

    {

      // Response wasn't compressed, return the original, uncompressed stream.

      result = webResponse.GetResponseStream();

      decompress = false;

    }

    // If response was actually compressed, decompress it.

    if (decompress)

    {

      // Decompress the input stream.

      reader = new BinaryReader(inputStream);

      result = new MemoryStream();

      writer = new BinaryWriter(result);

      int bytesRead;

      byte[] buffer = new byte[1024];

      do

      {

        // Read from compressed buffer and store the decompressed

        // bytes in the buffer.

        bytesRead = reader.Read(buffer, 0, buffer.Length);

        // Write decompressed buffer to the result stream.

        writer.Write(buffer, 0, bytesRead);

      } while (bytesRead > 0);

      writer.Flush();

      result.Position = 0;

    }

  }

  catch (Exception ex)

  {

    MessageBox.Show(ex.Message, "Exception", 

      MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

  }

  // Returned decompressed response.

  return result;

}



Listing Three



public override void ProcessMessage(SoapMessage message) 



// Hook into the web service process at various stages.

{

  switch (message.Stage) 

  {

    case SoapMessageStage.BeforeSerialize:

      break;

    case SoapMessageStage.AfterSerialize:

      // Capture and optionally modify SOAP request.

      ProcessRequest(message);

      break;

    case SoapMessageStage.BeforeDeserialize:

      // Capture and optionally modify SOAP response.

      ProcessResponse(message);

      break;

    case SoapMessageStage.AfterDeserialize:

      break;

    default:

      throw new Exception("invalid stage");

  }

}

public override Stream ChainStream(Stream stream)

// Save the stream representing the SOAP request or response



{

  oldStream = stream;

  newStream = new MemoryStream();

  return newStream;

}



Listing Four



private void ProcessRequest(SoapMessage message)

// Capture and optionally modify the SOAP request.

{

  newStream.Position = 0;

  using (MemoryStream memoryStream = new MemoryStream())

  {

    CopyStream(newStream, memoryStream);

    // Capture original SOAP request.

    OriginalSoapRequest = GetStreamText(memoryStream);

    // If user has checked the Modify SOAP Request and Response checkbox...

    if (modify)

    {

      // "Pretty-print" SOAP request XML with indentation.

      ModifiedSoapRequest = ModifySOAP(memoryStream, oldStream);

    }

    else

    {

      CopyStream(memoryStream, oldStream);

    }

  }

}

private void ProcessResponse(SoapMessage message)

// Capture and optionally modify the SOAP response.

{

  using (MemoryStream memoryStream = new MemoryStream())

  {

    CopyStream(oldStream, memoryStream);

    OriginalSoapResponse = GetStreamText(memoryStream);

    // If user has checked the Modify SOAP Request and Response checkbox

    if (modify)

    {

      ModifiedSoapResponse = ModifySOAP(memoryStream, newStream);

    }

    else

    {

      CopyStream(memoryStream, newStream);

    }

  }

  newStream.Position = 0;

}



Listing Five



<configuration>

 <system.web>

   <webServices>

     <soapExtensionTypes>

      <add type="SoapExDLL.SoapTraceModify, SoapExDll"

           priority="1"

           group="0" />

     </soapExtensionTypes>

    </webServices>

 </system.web>

</configuration>









4



