Extending and Customizing a Client



Extending and Customizing a Client

At times you will want to extend the client that Visual Studio .NET's Add Web Reference dialog box or wsdl.exe creates for you. For example, you may want to modify the data structure classes to have properties instead of fields.

Another possible customization is to override the HTTP settings on the client. This is possible by overriding the base class, SoapHttpClientProtocol, method GetWebRequest. This method on the base class is responsible for creating an HttpWebRequest object. Officially, this method needs only to return an object of type WebRequest. HttpWebRequest is one of those.

For example, you can set the timeout of the HttpWebRequest object to be 1 millisecond with the following code:

protected override WebRequest GetWebRequest(Uri uri) 
{
      HttpWebRequest wr = (HttpWebRequest)base.GetWebRequest( uri );
      wr.Timeout = 1;
      return wr;
}

This creates the MessageBox shown in Figure, when used from the previous section's exception handling code. Of course, the downside to doing something like this is fairly obvious: If you regenerate your client proxy class, then you will lose any modifications you made to the class.

6. A Network Timeout

graphics/04fig06.gif

To regenerate a client, such as after server updates that change the operation signatures, right-click the Web reference in Visual Studio .NET's Solution Explorer, and choose the Update Web Reference option (Figure).

7. Updating a Web Reference

graphics/04fig07.gif

In order to deal with this possible regeneration, subclass your generated proxy, and add the customizations there:

public class ServiceSubClass : localhost.Service1 
{
      public ServiceSubClass()
      {
      }

      protected override WebRequest GetWebRequest(Uri uri)
      {
            HttpWebRequest wr = (HttpWebRequest)base.GetWebRequest( uri );
            wr.Timeout = 1;
            return wr;
      }
}

Now, when the Service1 class is regenerated, you won't lose your code, because you are using the ServiceSubClass class instead:

try 
{
      ServiceSubClass s = new ServiceSubClass();
      MessageBox.Show( s.Divide( 10, 10).ToString() );
}
catch( SoapException fault )
{
      MessageBox.Show( fault.ToString() );
}
catch( WebException webx )
{
      MessageBox.Show( webx.ToString() );
}