The Most Distinguished Fault

There is one fault that distinguishes itself from all the rest by the level of support built in for it throughout the platform. This fault has its own attribute, its own behavior, works with any transport or protocol, is one of the few faults handled by the default fault converter, and even gets a mention in the standard that defines the concept of faults.

If you haven't figured out which fault I'm talking about by now, it's the MustUnderstand fault. I've talked about the MustUnderstand message header attribute and fault code before, but I'm pretty sure I haven't talked about the behavior (MustUnderstandBehavior) or exception type (it's an internal subclass of CommunicationException, so why worry about it though?).

MustUnderstand is an exceptional fault type in the sense that it is not dealt with at a particular protocol level. The meaning of a MustUnderstand fault is that some protocol that the sender speaks has not been properly dealt with by the receiver. In some cases, the sender doesn't care that the receiver can't understand a particular protocol. However, when the sender does care, it uses the MustUnderstand property of a message header to communicate that fact.

A MustUnderstand fault must be generated above any protocol channel that could potentially handle the message header. The fault is not an application fault, so it also must be generated below the application level. In WCF, the most common layer that meets these criteria is the dispatcher. The dispatcher checks through the message header collection looking to see if any header was marked as MustUnderstand but has not been marked as processed. If so, the dispatcher throws an exception. Performing this check in the runtime is prompted by the MustUnderstand endpoint behavior. There shouldn't be anyone attempting to handle the exception, so it will eventually reach a fault converter. At the fault converter, the exception is converted to a standardized MustUnderstand fault. If you're using SOAP 1.2, then you'll also have headers added to the fault message covering all of the other known unhandled message headers. Otherwise, all that is available is the header that was first noticed to not be understood.

Next time: A Historical, Awkwardly Named Fault