Freigeben über


Increasing the Maximum Fault Size

When the service sends a fault message with a large detail, my client is unable to read the fault. Changing the standard settings for the maximum message size doesn't help. How can I read large fault messages?

Fault messages have their own special quota that can be configured on the client proxy. For changing the settings of a proxy, you should immediately think about using a behavior. Luckily, that happens to work in this case. There is a MaxFaultSize property on the ClientRuntime, which we can get access to by supplying an IEndpointBehavior.

 public class SetMaxFaultSizeBehavior : IEndpointBehavior
{
   int size;

   public SetMaxFaultSizeBehavior(int size)
   {
      this.size = size;
   }

   public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
   {
   }

   public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
   {
      clientRuntime.MaxFaultSize = size;
   }

   public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
   {
   }

   public void Validate(ServiceEndpoint endpoint)
   {
   }
}

Let's use our new behavior to play with fault sizes. I've got a service that sends back a fault with no content, but we still have to deal with however big the rest of the fault message is. Then, the client will try connecting to the service with different maximum fault sizes to see what sizes work and what sizes don't.

 [ServiceContract]
public interface IService
{
   [OperationContract]
   void Operation();
}

public class Service : IService
{
   public void Operation()
   {
      throw new FaultException<string>("");
   }
}

class Program
{
   static void Main(string[] args)
   {
      Binding binding = new BasicHttpBinding();
      string uri = "https://localhost:8000/";
      ServiceHost host = new ServiceHost(typeof(Service));
      host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), uri);
      host.Open();

      int maxFaultSize = 1;
      while (true)
      {
         ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, new EndpointAddress(uri));
         factory.Endpoint.Behaviors.Add(new SetMaxFaultSizeBehavior(maxFaultSize));
         factory.Open();
         IService proxy = factory.CreateChannel();
         try
         {
            proxy.Operation();
         }
         catch (FaultException fault)
         {
            Console.WriteLine("Received fault with maxFaultSize={0}.", maxFaultSize);
            break;
         }
         catch (QuotaExceededException exception)
         {
            Console.WriteLine("Exceeded quota with maxFaultSize={0}.", maxFaultSize);
         }
         finally
         {
            factory.Close();
         }
         maxFaultSize++;
      }
      host.Close();

      Console.ReadLine();
   }
}

If we run the program, the last few lines are of interest.

 Exceeded quota with maxFaultSize=65.
Exceeded quota with maxFaultSize=66.
Exceeded quota with maxFaultSize=67.
Exceeded quota with maxFaultSize=68.
Exceeded quota with maxFaultSize=69.
Exceeded quota with maxFaultSize=70.
Received fault with maxFaultSize=71.

Evidently, our empty fault takes 71 bytes to transmit.

Next time: Tracing Across Services

Comments

  • Anonymous
    August 07, 2007
    If you've ever looked at a generated WSDL file, you may be wondering how all of the different parts of