Friday, April 27, 2012

Declaratively ignoring must understand headers

@YaronNaveh

A soap header may specify a "must understand" flag. This instructs any processing node to throw an exception if this header is not understood by it. Such a behavior is sometimes useful and sometimes very annoying, depending on the circumstances. Let's see how such header looks like in soap:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<callback s:mustUnderstand="1">http://www.server.com/</callback>
</s:Header>
<s:Body />
</s:Envelope>
view raw p.xml hosted with ❤ by GitHub

By default a Wcf service will validate all incoming mustUnderstand headers a client sends. If it does not understand them it will throw the famous 'Did not understand "MustUnderstand" header' exception. Typically you would instruct Wcf not to validate these headers like this:

[System.ServiceModel.ServiceBehavior(ValidateMustUnderstand = false)]
public class MyService : IServiceContract
{
// ...
}
view raw gistfile1.cs hosted with ❤ by GitHub

But this kind of "hard codes" this behavior to the service. Wouldn't it be nice to decide at the configuration level if we want such a behavior or not?

All we need to do is define this class:

public class ValidateMustUnderstandElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof (MustUnderstandBehavior); }
}
protected override object CreateBehavior()
{
return new MustUnderstandBehavior(false);
}
}
view raw gistfile1.cs hosted with ❤ by GitHub

Then in the config register it:

<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="validateMustUnderstand" type="WCF_Self_Hosted_Service48.ValidateMustUnderstandElement, WCF Self Hosted Service48, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
...
view raw gistfile1.xml hosted with ❤ by GitHub

And we can now configure our endpoint(s) with this behavior:

<behaviors>
<endpointBehaviors>
<behavior name="NewBehavior">
<validateMustUnderstand />
</behavior>
</endpointBehaviors>
...
view raw gistfile1.xml hosted with ❤ by GitHub

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

4 comments:

Uas Ku Sukses said...

Hi Yaron,

Kindly need help you advise about my problem.

I've tried to add MustunderstandBehaviour to my service

MustUnderstandBehavior mustUnderstand = new MustUnderstandBehavior(false);
mustUnderstand.ValidateMustUnderstand = false;

client.ChannelFactory.Endpoint.Behaviors.Add(mustUnderstand);


but it seems the mustundertand = "1", i want to change from "1" to "0"

Thanks.

Yaron Naveh (MVP) said...

to set mustunderstand to 0 you should implement a custom encoder. I believe you want to set it for outgoing requests while this post deals with incoming responses.

Uas Ku Sukses said...

Hi Yaron,

Yes, I've tried to make a custom encoder to make it became 0, but after im save the modified xml. I got the canonical issue. It seems the format should be followed canonical format.

Need your advise!!

Yaron Naveh (MVP) said...

not sure I understand, what is the canonical issue?