Tuesday, July 21, 2015

C# XML DOC include

I wrote some C# XML code documentation and neatly put it all in a separate XML file because it was referenced via <include> statements in template generated code. Why did only the <summary> appear and nothing else in the Sandcastle generated documentation? After a bit of swearing, I eventually noticed the tiny mistake of omitting the trailing /* from the path. A correct <include> statement might be like this:
/// <include file='codedoc.xml' path='MyApp/MyProject/MyClass/member[@name="MyMethod"]/*'/>

Notice the /* suffix. If you accidentally leave that off you only see the first child documentation element, which is probably the <summary>. Very easy to forget and not notice.

Wednesday, July 15, 2015

WCF Custom Headers and Silverlight

This post is now a part of computer history. See: Silverlight Death and Funeral


Sometime at least 5 years ago I needed to insert custom headers into outgoing messages from a WCF basic http client generated by slsvcutil.exe. The headers were expected on the server-side as proof that the Silverlight client was authenticated and trusted.

I spent many frustrating hours attempting to find a way of using custom Behaviors to automatically insert the headers. At the time I failed and assumed that behaviors were not supported by Silverlight clients. Instead, I used the technique of manually wrapping a context around the proxy to insert the headers. It's a cumbersome technique as you have to make the proxy call inside the using, which means a callback is needed from outside callers to keep the objects alive during the call. A skeleton of the technique looks like this:

// OLD-FASHIONED TECHNIQUE
private static void CallWrapper(DemoAppClient client, Action callback)
{
  using (OperationContextScope ocs = new OperationContextScope(client.Proxy.InnerChannel))
  {
    OperationContext.Current.OutgoingMessageHeaders.Add(MessageHeader.CreateHeader("name", "namespace", 123456));
    callback();
  }
}

One morning I suddenly decided I was sick of this ugly technique and went looking for a better way. I soon stumbled upon an article by Adil Mughal where he has minimal sample code that uses IEndpointBehavior and IClientMessageInspector to insert a custom header. This is exactly what I wanted to do all those years ago, but now I have no idea why I failed to discover how to use a behaviour back then. I'm not sure if it's because I was using older frameworks, or the documentation was unclear, or I was misdirected.

In any case, using a custom behavior is more elegant and the code is simpler because it avoids the need for a clumsy callback.


NOTE 24-Sep-2015


The article link above seems to be unreliable, so I have placed a copy of my custom behavior and custom inspector source code here:

http://www.orthogonal.com.au/computers/CustomBehavior.cs.txt

The behavior is added to the Silverlight client proxy by:

client = new ServiceClient(...);
client.Endpoint.Behaviors.Add(new CustomBehavior(new HeaderData(id, ticket)));


The HeaderData class is something I used to pass a set of useful information down through the behaviour into the inspector. You can replace it with whatever data your custom classes might need.

NOTE 18-Oct-2018


I forgot to explain how to safely extract the header information in the server-side.

var inheads = OperationContext.Current.IncomingMessageHeaders;
int index = inheads.FindHeader("name", "namespace");
if (index >= 0)
{
  T data = inheads.GetHeader("name", "namespace");
}

Note that 'behavior' is US spelling used in code. 'Behaviour' is AU and GB spelling.