Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Service Model » Answers » Faults   (RSS)

  • Embedding Arbitrary XML in Faults

    How can I directly craft the XML content that goes into a fault detail? Getting control over the detail element doesn't have to mean crafting the fault message yourself. While WCF requires that the fault detail be serializable using a data contract, remember that DataContractSerializer treats XmlElement as a special primitive type. This allows you to construct arbitrary content using XmlElement when your content can be represented as a rooted document. Due to the automatic conversion process of FaultException to a fault message, you don't need to construct a data contract to act as a wrapper. Here's a sample that builds some content in an XmlElement and uses it to construct a fault. I made the method return a Message so that I could look at the response more easily but you can use any contract you want. [ServiceContract] public interface IMyService { [OperationContract] Message Fail(); } public class MyService : IMyService { public Message Fail() { XmlDocument document = new XmlDocument(); XmlElement root = document.CreateElement( "tag" ); root.SetAttribute( "attributeName" , "value" ); XmlElement subtag = document.CreateElement( "moretags" ); subtag.InnerText = "blah" ; root.AppendChild(subtag); throw new FaultException<XmlElement>(root); } } public class Program { static void Main( string [] args) { string address = "http://localhost:8000/" ; BasicHttpBinding binding = new BasicHttpBinding(); ServiceHost host = new ServiceHost( typeof (MyService), new Uri(address)); host.AddServiceEndpoint( typeof (IMyService), binding, "" ); host.Open(); ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(binding); IMyService proxy = factory.CreateChannel( new EndpointAddress(address)); Message response = proxy.Fail(); Console.WriteLine(response.ToString()); Console.ReadLine(); host.Close(); } } That code produces a fault message that looks like the following. < s:Envelope xmlns:s ="http://schemas.xmlsoap.org/soap/envelope/" > < s:Header /> < s:Body > < s:Fault > < faultcode > s:Client </ faultcode > < faultstring xml:lang ="en-US" > The creator of this fault did not specify a Reason. </ faultstring > < detail > < tag attributeName ="value" > < moretags > blah </ moretags > </ tag > </ detail > </ s:Fault > </ s:Body > </ s:Envelope > Depending on how much hand-crafting you want, XmlDocument lets you simplify the process even further. For Read More...
  • 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 = "http://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(); Read More...

Copyright © 2006 Microsoft Corporation. All Rights Reserved. | Terms of Use | Privacy Statement | Contact Us