The second most distinguished fault, with almost as many special cases and discussion as the MustUnderstand fault I talked about last week, ended up not making it into the product. Some form of the fault is still in there of course, but it lost its mouthful of a name: the InvalidCardinalityAddressing fault.

An InvalidCardinalityAddressing fault occurs when you have more or fewer copies of a header than was expected. For instance, messages are expected to have at most one MessageID. Having twelve MessageIDs would be frowned upon. On the basic MessageHeaders collection, this is checked when accessing the Action, FaultTo, From, MessageID, ReplyTo, or To properties. Detecting that there's an InvalidCardinalityAddressing problem only takes place when someone looks at the message and in particular looks at the offending header. Given our extensible protocol stack, there's no way to predict who the first person to look at a particular header will be. Therefore, this is one of the few faults that can potentially occur at any layer.

Since there's no longer an InvalidCardinalityAddressingException to use in situations like this, you should be expecting a MessageHeaderException, one of the subtypes of ProtocolException, to come back instead.

public class MessageHeaderException : ProtocolException
{
public MessageHeaderException();
public MessageHeaderException(string message);
protected MessageHeaderException(SerializationInfo info, StreamingContext context);
public MessageHeaderException(string message, bool isDuplicate);
public MessageHeaderException(string message, Exception innerException);
public MessageHeaderException(string message, string headerName, string ns);
public MessageHeaderException(string message, string headerName, string ns, bool isDuplicate);
public MessageHeaderException(string message, string headerName, string ns, Exception innerException);
public MessageHeaderException(string message, string headerName, string ns, bool isDuplicate, Exception innerException);

public string HeaderName { get; }
public string HeaderNamespace { get; }
public bool IsDuplicate { get; }
}

This exception is also generated by the standard wire faults InvalidAddressingHeader (subcode InvalidCardinality) and MessageAddressingHeaderRequired. MessageAddressingHeaderRequired translates to IsDuplicate = false while InvalidAddressingHeader.InvalidCardinality translates to IsDuplicate = true. This interpretation of duplicates is mandated by the SOAP binding in the WS-Addressing specification so I'm hoping that everyone is doing it correctly. InvalidCardinality is otherwise vague from the name about whether it means too many or too few copies so it would be easy to get this wrong. Knowing that also helps explain why using InvalidCardinalityAddressingException for both cases was so awkward.

Next time: Consuming Faults, Part 1