BrainHzSoftware.com

WCF Extensibility

Posted by Scott Reed on 11th August 2010

This was in the works for a long time, but today I gave a GeekSpeak talk on WCF Extensibility. The hosts were very nice. I have known Lynn for a while now, but it was great to finally meet Glen. Despite the fact that I was extremely nervous I only screwed up once :)

Here are the demos.

Tags: , ,
Posted in Talks | Comments Off

The WCF REST Family

Posted by Scott Reed on 26th June 2010

Another year, another San Diego Code Camp :) I signed up for this talk way in advance, and forgot to check up on it. There were a couple of presenters giving similar talks. What I tried to do was demo my way through WCF REST support, WCF Data Services, and WCF RIA Services, explaining what each one was and how it differed from the others. I had a *TON* of questions and so the talk ran a little long, and I didn’t get to do any of my RIA demos. I think I stopped after slide 15. However, I did have a couple people come up to me afterwords and say that my talk was there favorite talk of the whole code camp, so in that respect – mission accomplished! The room was jam packed standing room only, so thanks to everyone who came out.

Here are the Slides and Demos

Tags: , , ,
Posted in Talks | Comments Off

Calling Amazon AWS through SOAP using WCF

Posted by Scott Reed on 13th May 2010

I knew already that Amazon had two ways of calling their services. The first was by consuming the WSDL metadata and calling through SOAP, and the second was through REST. Of course the REST would be too cumbersome by itself but not to fear – there is a SDK which makes that easier from common languages like Java and .NET. But the SOAP should be brain dead simple to consume right? Wrong. After searching the forums for a while I figured out that somebody had managed to get it working through WSE 2.0 but nobody had managed to get it working from WCF. I thought to myself – “Self, I can’t allowed this to happen”. Myself agreed.

OK the first thing was to get it to work any way I could. While I was searching the forums I came across this post which describes how to call AWS using SOAPSonar. So I downloaded my trial edition and gave it a whirl.Using SOAPSonar enterprise I was able to add a certificate that I had saved earlier called ‘brainhz-cert.cer’ and call the service. Excellent. So now all I needed was to do this same task in WCF.

The first step was figuring out how they were securing their service. After looking through their docs I found a couple of helpful snippets.

  1. AWS does not implement a full public key infrastructure. The certificate information is used only to authenticate requests to AWS. AWS uses X.509 certificates only as carriers for public keys and does not trust or use in any way any identity binding that might be included in an X.509 certificate. Pasted from
  2. Amazon does not store your private key.  Creating a new certificate/private key pair invalidates your old one.  This only affects your X.509 key used to authenticate AWS requests.  It does not affect the ssh keypairs you use to log into instances (linux) or retrieve their password (windows). Pasted from
  3. The WS-Security 1.0 specification requires you to sign the SOAP message with the private key associated with the X.509 certificate and include the X.509 certificate in the SOAP message header. Specifically, you must represent the X.509 certificate as a BinarySecurityToken as described in the WS-Security X.509 token profile (also available if you go to the OASIS-Open web site). Pasted from

From this I was able to deduce that they were using the WSS SOAP Message Security X.509 Certificate Token Profile 1.0

I guessed that I needed to use Message based security with the Certificate credential type, but I double checked myself on the MSDN website.

WSS SOAP Message Security X.509 Certificate Token Profile 1.0
<basicHttpBinding>
  <security mode="Message">
    <message credentialType="Certificate"/>
  </security>
</basicHttpBinding>

Pasted from

I needed to specify which certificate I was going to use. It looked like I already had one in my Personal store (sometimes called the My store).

<endpointBehaviors>
	<behavior name="cert">
		<clientCredentials>
			<clientCertificate storeLocation="CurrentUser" storeName="My"
				 x509FindType="FindByThumbprint"
				findValue="6b 6a e8 ad b6 61 9c 1d a2 75 21 e4 4a d7 15 53 11 e6 72 27"/>
		</clientCredentials>
	</behavior>
</endpointBehaviors>

After adding that the next error that I ran into was this:
“The service certificate is not provided for target ‘http://ec2.amazonaws.com/’. Specify a service certificate in ClientCredentials.”

OK, so I needed the serviceCertificate. I used FireFox and hit https://ec2.amazonaws.com/ and saved the certificate. Then I imported it into my trusted people store.
Then I went in and added the following in my endpoint behavior:

<serviceCertificate>
	<defaultCertificate storeLocation="CurrentUser" storeName="TrustedPeople"
		x509FindType="FindByThumbprint" findValue="29 ca cd 8f 43 2e ff 31 f2 7f e5 70 e9 2e 1a f3 9e 1b f8 e8"/>
	<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/>
</serviceCertificate>

I had high hopes, before running this time, but no. The next error was:
“Private key is not present in the X.509 certificate”. When I looked at the certificate in the store, sure enough I did not see the “You have a private key that corresponds to this certificate” at the bottom.
Weird that it worked for SOAPSonar, but whatever. I went to Amazon, created and downloaded another certificate, combined the two and put them in my personal store. I then had to switch the certificate thumbprint to the one starting with 72 46.

After doing all of that I received a very strange error.
“Value (xmlenc#) for parameter Version is invalid. Version not well formed. Must be in YYYY-MM-DD format.”
WTF? I had never seen this one before, and I didn’t really know what sort of black magic was going on beneath me. So I turned on message level tracing, did some searching, and ended up trying two things:

  1. Switching the algorithmSuite from Default (Basic256), to (Basic128).
  2. Switching the OperationContract ProtectionLevel to Sign only.

WARNING: this is a HACK do not do this.
I went into the generated code into Reference.cs and changed the attribute on DescribeImages.

        [OperationContract(Action="DescribeImages", ReplyAction="*", ProtectionLevel=ProtectionLevel.Sign)]

Now fervently praying, I ran again. Bad news and good news.
Bad news was it didn’t work, good news was it was a message size issue, which I have fixed so many times in the past. Because we were using Message security I couldn’t turn on streaming. So I had to just up the maximum.
maxBufferSize=”9999999″ maxReceivedMessageSize=”9999999″

After cranking up the number high enough I got
System.ServiceModel.Security.MessageSecurityException occurred
Message=Security processor was unable to find a security header in the message. This might be because the message was an unsecured fault or because there was a binding mismatch between the communicating parties. This can occur if the service is configured for security and the client is not using security.

This was starting to make me mad. I was saying things that are unfit for children’s ears to my computer. After tracing, I discovered that this was related to the fact that Amazon messages are only secured one way.
The responses, or this response anyway, seemed to be unsecured. After some searching I found a hotfix for this issue in WCF.

http://support.microsoft.com/kb/971493

However, it required a customBinding. ARRGH!

Now the next step was to figure out which of the properties needed to be set so that it matched what I was doing before.
I created a program that created the two bindings, and compared the binding elements using reflection. The outcome of that program was the following binding declaration:

<binding name="customWithUnsecuredResponse">
	<security authenticationMode="MutualCertificate"
		 allowSerializedSigningTokenOnReply="true"
		 defaultAlgorithmSuite="Basic128"
		 messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
		 enableUnsecuredResponse="true"
		 securityHeaderLayout="Lax"
		 />
	<textMessageEncoding />
	<httpTransport maxBufferSize="9999999" maxReceivedMessageSize="9999999" />
</binding>

I particularly liked the message security version which has to be high on the list of longest names in all of .NET. Also notice the enableUnsecuredResponse = true.

After running one more time…

I bet the suspense is killing you…


IT WORKED!!!

I spent the next several minutes whooping it up. After having done it, I can honestly say that may be the only person in the world that has been stupid enough to try and get this working :)

Tags: , , , ,
Posted in Cloud | Comments Off

REST and SOAP metadata hack

Posted by Scott Reed on 1st July 2009

I had a request to post the information on “the hack” that I presented in my demo this past weekend.

First a little bit about why I needed the hack in the first place. Recall that the goal was to get a single service to support both REST and SOAP. Yes I could have done this another way by simply having two separate services and factoring the common code into a shared assembly, but I liked the idea of them sharing the same base address. I had no problems implementing GET methods with the same interface. The problem arose when I wanted to support upload. In WCF when uploading files of arbitrary length you should probably implement streaming. Streaming requires the body of the message to consist of a single Stream object. Of course I also need to send over the name or title of the picture. In REST the name should be sent via the URL and in SOAP it needs to be a header. As it turns out this means I have to support two separate methods. So I factored a single interface into three: a common, a SOAP, and a REST version.

[ServiceContract]
public interface IPictureServiceCommon
{
  [OperationContract]
  [WebGet(UriTemplate = "titles")]
  string[] GetPictureTitles();</code><code>[OperationContract]
  [WebGet(UriTemplate = "{title}")]
  Stream GetPicture(string title);
}

[ServiceContract]
public interface IPictureServiceRest : IPictureServiceCommon
{
  [OperationContract]
  [WebInvoke(UriTemplate = "{title}", Method = "PUT")]
  void UploadPicture(string title, Stream picture);
}

[ServiceContract]
public interface IPictureServiceSoap : IPictureServiceCommon
{
  [OperationContract]
  void UploadPicture(FileMessage fileMessage);
}

Unfortunately WCF as it stands right now (in .NET 3.5 SP1) only supports turning Metadata on and off at the service level. So when I try to access the Metadata for the REST endpoint it ignores the URI Template aspect and tells me that I have an illegal method.

System.InvalidOperationException: For request in operation UploadPicture to be a stream the operation must have a single parameter whose type is Stream.

So that is where the hack came in as I needed to be able to turn off Metadata for a single endpoint. It turns out it was quite simple (although very hacky).

var host = new ServiceHost(typeof(PictureService));
// This is SUCH a HACK, but it works...
Assembly serviceModel = typeof(ServiceHostBase).Assembly;
Type type = serviceModel.GetType("System.ServiceModel.Description.ServiceMetadataContractBehavior");
var behavior = (IContractBehavior)Activator.CreateInstance(type, new object[] { true });  

foreach (ServiceEndpoint ep in   host.Description.Endpoints)
{
  // apply the hack to all REST endpoints
  if (ep.Binding is WebHttpBinding)
    ep.Contract.Behaviors.Add(behavior);
  Console.WriteLine(ep.Address);
}
host.Open();

Tags: , ,
Posted in WCF | Comments Off

Service side AOP with WCF

Posted by Scott Reed on 26th March 2009

Just as you want to aspect out the functionality around the client calling a service, so you may also want to aspect out the functionality around a service receiving a call from a client. WCF already has something built in for this: the OperationInvoker. Although the OperationInvoker is an Operation level construct I wanted to be able to take it a step further and be able to turn these aspects on or off via the config file. Furthermore I wanted to be able to apply these behaviors at either the endpoint or the service level depending on what I was debugging. Specifically when I encountered an issue in the service not behaving correctly I wanted to be able to turn on logging or possibly performance counters to see what the problem was.

    As I have mentioned before: the three steps to WCF extensibility are here:
  1. Implement the interface you are trying to plug in (in my case IOperationInvoker)
  2. Author a behavior to replace the WCF functionality with your functionality written in step 1
  3. (optional) If you are plugging into the config file you will need to author a class that describes your config element
  4. (optional) If you are applying the behaviors programmatically consider creating a custom service host that automatically applies your behaviors

OK, so on to step 1:

class LoggingOperationInvoker : IOperationInvoker
{
	private static readonly ILog log = LogManager.GetLogger(typeof(LoggingOperationInvoker));
	readonly IOperationInvoker innerOperationInvoker;
	private readonly string methodName;
	private readonly bool writeInput;
	private readonly bool writeOutput;
	private readonly bool ignored;

	public LoggingOperationInvoker(IOperationInvoker innerOperationInvoker,
		string methodName, bool writeInput, bool writeOutput, bool ignored)
	{
		this.innerOperationInvoker = innerOperationInvoker;
		this.methodName = methodName;
		this.writeInput = writeInput;
		this.writeOutput = writeOutput;
		this.ignored = ignored;
	}

	public object[] AllocateInputs()
	{
		return innerOperationInvoker.AllocateInputs();
	}

	public object Invoke(object instance, object[] inputs, out object[] outputs)
	{
		if (!ignored && writeInput)
			LogUtils.LogMethodCall(log, methodName, inputs);
		// Invoke the operation using the inner operation invoker.
		object result;
		try
		{
			result = innerOperationInvoker.Invoke(instance, inputs, out outputs);
		}
		catch (Exception ex)
		{
			if (!ignored && writeOutput)
				LogUtils.LogMethodThrow(log, methodName, ex);
			throw;
		}
		if (!ignored && writeOutput)
			LogUtils.LogMethodReturn(log, methodName, result);
		return result;
	}

	public IAsyncResult InvokeBegin(object instance, object[] inputs,
		AsyncCallback callback, object state)
	{
		if (!ignored && writeInput)
			LogUtils.LogMethodCall(log, methodName, inputs);
		return innerOperationInvoker.InvokeBegin(instance, inputs, callback, state);
	}

	public object InvokeEnd(object instance, out object[] outputs, IAsyncResult asyncResult)
	{
		// Finish invoking the operation using the inner operation invoker.
		object result;
		try
		{
			result = innerOperationInvoker.InvokeEnd(instance, out outputs, asyncResult);
		}
		catch (Exception ex)
		{
			if (!ignored && writeOutput)
				LogUtils.LogMethodThrow(log, methodName, ex);
			throw;
		}
		if (!ignored && writeOutput)
			LogUtils.LogMethodReturn(log, methodName, result);
		return result;
	}

	public bool IsSynchronous
	{
		get { return innerOperationInvoker.IsSynchronous; }
	}
}

Notice that there are lots of variables in the constructor which let this particular operation invoker know what to log. We will talk about how all of this gets set in just a minute.

In order to get that plugged in to WCF we need to to implement a behavior (here an operation behavior).

public class LoggingOperationBehavior : Attribute, IOperationBehavior
{
	private readonly bool writeInput;
	private readonly bool writeOutput;
	private readonly ICollection<string> ignoredMethodNames;

	public LoggingOperationBehavior(bool writeInput, bool writeOutput, ICollection<string> ignoredMethodNames)
	{
		this.writeInput = writeInput;
		this.writeOutput = writeOutput;
		this.ignoredMethodNames = ignoredMethodNames;
	}

	public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
	{
	}

	public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
	{
	}

	public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
	{
		bool ignored = ignoredMethodNames.Contains(dispatchOperation.Name);
		dispatchOperation.Invoker = new LoggingOperationInvoker(dispatchOperation.Invoker, dispatchOperation.Name, writeInput, writeOutput, ignored);
	}

	public void Validate(OperationDescription operationDescription)
	{
	}
}

This step may be the easiest of the lot. We simply pass along the things we are constructed with and set the invoker.

On to step 3. I want to be able to plug this in to the config file at both the endpoint behavior and the service behavior level. Let’s start at the endpoint level. In order to plug into the config file at the endpoint level we need a endpoint behavior extension element. But the extension element is responsible for creating a behavior, and we don’t yet have an endpoint behavior. So we will have to create both, ugh!

public class LoggingEndpointBehavior : IEndpointBehavior
{
	private readonly bool writeInput;
	private readonly bool writeOutput;
	private readonly ICollection<string> ignoredMethodNames;

	public LoggingEndpointBehavior(bool writeInput, bool writeOutput, ICollection<string> ignoredMethodNames)
	{
		this.writeInput = writeInput;
		this.writeOutput = writeOutput;
		this.ignoredMethodNames = ignoredMethodNames;
	}

	public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
	{
	}

	public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
	{
	}

	public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
	{
		foreach (DispatchOperation dispatchOp in endpointDispatcher.DispatchRuntime.Operations)
		{
			bool ignored = ignoredMethodNames.Contains(dispatchOp.Name);
			dispatchOp.Invoker = new LoggingOperationInvoker(dispatchOp.Invoker, dispatchOp.Name, writeInput, writeOutput, ignored);
		}
	}

	public void Validate(ServiceEndpoint endpoint)
	{
	}
}

public class LoggingEndpointBehaviorExtensionElement : BehaviorExtensionElement
{
	private const string WriteInputPropertyName = "writeInput";
	private const string WriteOutputPropertyName = "writeOutput";
	private const string IgnoredMethodNamesPropertyName = "ignoredMethodNames";

	public override Type BehaviorType
	{
		get { return typeof(LoggingEndpointBehavior); }
	}

	protected override object CreateBehavior()
	{
		var listIgnoredMethods = (ICollection<string>)IgnoredMethodNames.Split(',');
		return new LoggingEndpointBehavior(WriteInput, WriteOutput, listIgnoredMethods);
	}

	[ConfigurationProperty(WriteInputPropertyName, DefaultValue = true)]
	public bool WriteInput
	{
		get { return (bool)base[WriteInputPropertyName]; }
		set { base[WriteInputPropertyName] = value; }
	}

	[ConfigurationProperty(WriteOutputPropertyName, DefaultValue = true)]
	public bool WriteOutput
	{
		get { return (bool)base[WriteOutputPropertyName]; }
		set { base[WriteOutputPropertyName] = value; }
	}

	[ConfigurationProperty(IgnoredMethodNamesPropertyName, DefaultValue = "")]
	public string IgnoredMethodNames
	{
		get { return (string)base[IgnoredMethodNamesPropertyName]; }
		set { base[IgnoredMethodNamesPropertyName] = value; }
	}
}

You can see that the EndpointBehavior is basically the same as the OperationBehavior, but because we start at a higher level (the endpoint) we have to dig a little deeper to get to the individual operations. The LoggingEndpointBehaviorExtensionElement allows the WriteInput, WriteOutput and IgrnoredMethods names be set correctly in the config file.

I will leave it as an exercise to the reader to implement the service behavior, but it is almost exactly like the other two.

The last thing that I want to do is show you how to turn these things on and off from the config file. Here is an excerpt from the system.serviceModel section

		<extensions>
			<behaviorExtensions>
				<add name="logEndpointCalls" type="Interface.LoggingEndpointBehaviorExtensionElement, Interface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
			</behaviorExtensions>
		</extensions>
		<services>
			<service name="Service.MyService">
				<endpoint address="" behaviorConfiguration="log"
                  		binding="netTcpBinding"
                  		contract="Interface.IService" />
			</service>
		</services>
		<behaviors>
			<endpointBehaviors>
				<behavior name="log">
					<logEndpointCalls />
				</behavior>
			</endpointBehaviors>
		</behaviors>

That’s it, happy WCFing…

Tags: ,
Posted in WCF | Comments Off

Client side AOP in WCF

Posted by Scott Reed on 22nd March 2009

I love Aspect Oriented Programming. The idea of centralizing the code of a specific nature (logging, performance counting/monitoring, exception handling, etc.) is very compelling form a clean code point of view. WCF allows me to get this "for free". I have been aspecting out my calls to WCF services for a while now, but I recently discovered a better way that allows for type safety and intellisense.

The calls used to look like this:

helper.CallService("GetSamplesByState", state);

But they now look like this:

helper.CallService(p => p.GetSamplesByState(state));

Here is the code with the changes highlighted:

using System;
using System.Reflection;
using System.ServiceModel;

namespace Common.Utilities
{
    public class CommunicationHelper<T> : IDisposable
        where T : class
    {
        ChannelFactory<T> factory;
        T channel;

        public CommunicationHelper(string channelName)
        {
            using (TimedLock.Lock(factory))
            {
                factory = new ChannelFactory<T>(channelName);
            }
        }

        public string Address
        {
            get
            {
                using (TimedLock.Lock(factory))
                {
                    return factory.Endpoint.Address.ToString();
                }
            }
        }

        private void EnsureChannelCreated()
        {
            using (TimedLock.Lock(factory))
            {
                if ((channel == null) ||
                    (((IClientChannel)channel).State == CommunicationState.Faulted))
                {
                    channel = factory.CreateChannel();
                }
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool isDisposing)
        {
            if (isDisposing)
            {
                using (TimedLock.Lock(factory))
                {
                    factory.Close();
                }
            }
        }

        public void CallService(string methodName, params object[] args)
        public void CallService(Action<T> handler)
        {
            CallServiceInternal(methodName, args);
            CallServiceInternal(handler);
        }

        public TReturnType CallService<TReturnType>(string methodName, params object[] args)
        public object CallService(Func<T,object> handler)
        {
            return (TReturnType)CallServiceInternal(methodName, args);
            return CallServiceInternal(handler);
        }

        internal object CallServiceInternal(Delegate handler)
        {
            object returnObj = null;

            try
            {
                EnsureChannelCreated();
                try
                {
                    if (factory != null)
                    {
                        using (TimedLock.Lock(factory))
                        {
                            MethodInfo methodInfo = typeof(T).GetMethod(methodName);
                            returnObj = methodInfo.Invoke(channel, args);
                            returnObj = handler.DynamicInvoke(channel);
                        }
                    }
                }
                catch (TargetInvocationException e)
                {
                    throw e.InnerException;
                }
            }
            catch (FaultException)
            {
                throw; // don't want to catch FaultExceptions which are a subclass of CommunicationException
            }
            catch (CommunicationException e)
            {
                throw new CommunicationHelperException(e.Message, e);
            }
            catch (TimeoutException e)
            {
                throw new CommunicationHelperException(e.Message, e);
            }

            return returnObj;
        }
    }
}

Tags: ,
Posted in WCF | Comments Off

Presenting/Attending SoCal Code Camp San Diego 2008

Posted by Scott Reed on 30th June 2008

I presented my first code camp talk this weekend and it was a great experience. Here are the talks I attended:

Day 1

A Technical Drilldown into Microsoft’s ESB Guidance
by Brian Loesgen

Agile Programming
by Llewellyn Falco & Carl Manaster

Lunch

Fixing Legacy Code
by Jason Kerney & Llewellyn Falco

Aspect Oriented Programming in .NET, an Introduction with ASPECT.NET
by Adnan Masood

Agile Coding Techniques for Legacy Apps
by Woody Zuill

Dynamic Languages and the DLR
by Mike Vincent

Day 2

Integrating Silverlight 2.0 into an Existing Web Application
by Robert Altland

Creating Cmdlets for PowerShell
by Steve Evans

Windows Workflows (300 Level)
by Mark Bosley

Overview of the Composite Application Guidance for WPF
by Adam Calderon

Followed by my session on WCF Advanced Topics…

I was amazed and dismayed at the number of presenters who did nothing but show slides. Here is some advice that I can offer newbie speakers

  1. Tell a story
  2. Use something besides just powerpoint (use the whiteboard, do some demos, etc)

Tags: ,
Posted in Code Camp, Talks | Comments Off

WCF Extensibility Explained

Posted by Scott Reed on 7th February 2008

I just finished a huge WCF teaching tour. I was teaching every other week for several months. During that time I finally realized the best way to teach WCF extensibility.

But first some background. There are two types of extensibility in WCF – channel layer extensibility and service model extensibility. At the channel layer you are dealing explicitly with messages. There are only two reasons why you might want to write a channel:

  1. You need to create a new way of transporting the bits to the other process. For example you might want to create a file channel, that uses file sharing to move the bits across, or a UDP channel. BTW – you can find samples for doing both of those things, so don’t reinvent the wheel.
  2. You need a single outgoing message to result in more than one outgoing message. Most of the protocol channels fall into this category: security, transactions, reliable messaging, chunking, etc.

That’s it. There are no other valid reasons. The channel layer is more complicated than the service model layer, and more difficult to get right, so avoid it when you can.

With that out of the way, let’s focus on the other type of extensibility – service model extensibility. At this layer its hard to understand why it is so complicated. It all goes back to the WCF design goal – To be the single best way of getting any two pieces of software to communicate under any circumstances. In other words the WCF team has to support not only any known way of communicating, but any unknown way of communicating as well. Not just any way that exists now, but any way that might ever be invented. With a design goal like that you have to be REALLY flexible. And with flexibility comes the lesser liked ugly cousin – Complexity.

So the way extensibility at the service model layer works is like this. You have to author two classes. One is the actual functionality that you are trying to provide, and the other is used to plug that into the WCF plumbing (more about that later).

So for the first class what functionality can be extended? Well, there are so many hooks in WCF that it would be impossible to list them all, but some of the interfaces you might need to implement are listed here (courtesy of MSDN)

Interface Description
ICallContextInitializer Defines the methods that enable the initialization and recycling of thread-local storage with the thread that invokes user code.
IChannelInitializer Defines the interface to notify a service or client when a channel is created.
IClientMessageFormatter Defines methods that are used to control the conversion of messages into objects and objects into messages for client applications.
IClientMessageInspector Defines a message inspector object that can be added to the MessageInspectors collection to view or modify messages.
IClientOperationSelector Defines the contract for an operation selector.
IDispatchMessageFormatter Defines methods that deserialize request messages and serialize response messages in a service application.
IDispatchMessageInspector Defines the methods that enable custom inspection or modification of inbound and outbound application messages in service applications.
IDispatchOperationSelector Defines the contract that associates incoming messages with a local operation to customize service execution behavior.
IErrorHandler Allows an implementer to control the fault message returned to the caller and optionally perform custom error processing such as logging.
IInputSessionShutdown Defines the contract that must be implemented to shut down an input session.
IInstanceContextInitializer Defines the methods necessary to inspect or modify the creation of InstanceContext objects when required.
IInstanceContextProvider Implement to participate in the creation or choosing of a System.ServiceModel.InstanceContext object, especially to enable shared sessions.
IInstanceProvider Declares methods that provide a service object or recycle a service object for a Windows Communication Foundation (WCF) service.
IInteractiveChannelInitializer Defines the methods that enable a client application to display a user interface to collect identity information prior to creating the channel.
IOperationInvoker Declares methods that take an object and an array of parameters extracted from a message, invoke a method on that object with those parameters, and return the method’s return value and output parameters.
IParameterInspector Defines the contract implemented by custom parameter inspectors that enables inspection or modification of information prior to and subsequent to calls on either the client or the service.

Pasted from here

However, it is the second class is really the focus of this blog entry. This class is responsible for plugging the first class into WCF. You can extend WCF at three different levels, as shown in the diagram below. At the innermost level in red you can extend WCF for a single operation. You can also effect an entire endpoint (shown in purple), or even the entire service consisting of all endpoints.

Let me back up for just a second. The WCF service model extensibility is very similar to the extensibility model of you car. You open up the hood, then you can add parts, remove parts, change one part for another, but you have to know exactly what you are doing. Then you close the hood and use the newly altered engine to actually drive the car. So although it is not exactly easy, if you have seen a show like “Pimp My Ride”, you know there is nothing you can’t do. The same is true of WCF. WCF calls your behavior and it passes your behavior the “engine” at the place you trying to extend it. You alter the plumbing in any way you want, and then WCF uses the plumbing you have altered to actually run your service / endpoint / operation.

So if I am implementing an IServiceBehavior in the ApplyDispatchBehavior method I get a ServiceHostBase class which I can manipulate in any way I see fit. Actually I get two pieces of information. The first is the description of what should happen or the “manual”, and the second is the engine.

public interface IServiceBehavior
{
	void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase);
	// other members elided for clarity...
}

After the ApplyDispatchBehavior is called and my behavior has altered the ServiceHostBase, WCF uses the altered ServiceHostBase to “drive” my service.

Similarly for IEndpointBehavior in both the ApplyClientBehavior and the ApplyDispatchBehavior I get the WCF description and the plumbing for an endpoint.

public interface IEndpointBehavior
{
	void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime);
	void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher);
	// other members elided for clarity...
}

The same is true for an Operation.

public interface IOperationBehavior
{
	void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation);
	void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation);
	// other members elided for clarity...
}

The last part of the extensibility mechanism is how WCF actually finds out about the behavior that you wrote in step 2. This can be done in one of three ways: by applying an attribute, by programmatically adding the behavior (i.e. host.Description.Behaviors.Add) or by authoring a third class which inherits from BehaviorExtensionElement that describes what your behavior’s XML element can contain.

Tags: ,
Posted in WCF | Comments Off

WCF Streaming – When to close the stream

Posted by Scott Reed on 30th August 2007

WCF sets the default message size really low. I think the reason they did this was to slap the face of all the lazy developers out there. Just to wake them up. A limit that low is almost guaranteed to be hit in development rather than production. That is the WCF team saying "SMACK! Pay attention, what you do here is very important to the performance of the app."

There are three ways of fixing this "problem".

  1. Increase the maximum message size This will only get you so far, and should only be used when two conditions apply. The first is that you know the maximum size a message can be, and the second is that that maximum size multiplied by the maximum number of simultaneous messages can fit in the lowest amount of memory that your service application can run with.
  2. Chunk the message into smaller messages This is especially a good solution when ordering is not needed. For example if I was going to send my CD collection over the wire I might chose to chunk it. If you happen to get the Beatles before ABBA (cough, um… that one must be my wife’s CD) it is no big deal. However if you were to chunk a file, there could be problems because if chunk #3 arrived before chunk #2 you now have a corrupted file.
  3. Turn on streaming This one should really only be used if you are simply copying that network stream to some other input / output device, like your monitor or a hard drive. To do this means you have to have a special contract which takes a stream as the single message body.

Let’s take a simple file storage service as an example. The Store file could have a single Stream parameter, but what about the other information that needs to be passed along with the Stream, like the name and author? The contract will probably end up looking something like this:

	[MessageContract]
	public class FileMessage
	{
		[MessageHeader]
		public string fileName;

		[MessageBodyMember]
		public Stream fileStream;

		public FileMessage()
		{
		}

		public FileMessage(string fileName, Stream fileStream)
		{
			this.fileName = fileName;
			this.fileStream = fileStream;
		}
	}

	[ServiceContract]
	public interface IFileService
	{
		[OperationContract]
		void StoreFile(FileMessage fileMessage);
		[OperationContract]
		Stream GetFile(string fileName);
	}

When you go to implement the contract people often wonder when to close the stream. The advice given in "Programming WCF Services" is a little confusing (and not entirely correct) around this topic. Page 204 states:

When the client passes a request stream to the service, the service may read from the stream long after the client is gone. The client has no way of knowing when the service is done using the stream. Consequently the client should not close the stream— WCF will automatically close the client-side stream once the service is done using the stream.

A similar problem exists when the client interacts with a response stream. The stream was produced on the service side, and yet the service does not know when the client is done using the stream, nor can WCF help, because it has no idea what the client is doing with the stream. The client is always responsible for closing reply streams.

The first paragraph is not really correct because if the client is calling the service synchronously then it knows exactly when to close the stream. It turns out that the second paragraph is the only case when you don’t close the stream. So really to summarize – Always close the stream, except when you don’t know when to close it. The only time that is true is when the stream is being returned from the service and you don’t know when it has finished being written into the outgoing buffer. Here is the code first on the client side:

using (var fs = new FileStream(uploadPath, FileMode.Open, FileAccess.Read))
{
	client.StoreFile(new FileMessage(uploadPath, fs));
} // NOTE: the stream is closed here
...
using (Stream s = client.GetFile(downloadFileName))
{
	// do something with the stream
} //NOTE: the stream is closed here

Then on the service side:

public Stream GetFile(string fileName)
{
	// this is the only place that we don't close the stream
	// WCF does it for us in this case, whenever it is done sending the message
	return new FileStream(fileName, FileMode.Open);
}

public void StoreFile(FileMessage msg)
{
	// do something with the stream
	msg.fileStream.Close();
}

Tags: ,
Posted in WCF | Comments Off

WCF Remoting vs. Asmx Web Services

Posted by Scott Reed on 29th June 2006

I have had the pleasure (or excruciating pain depending on the point of view) of interviewing a lot of candidates for the various technical positions that are open at my company. One of the questions I often ask, “If I have two machines and I want to communicate between them, what are some of my options in .NET?” Far too often when the candidate mentions .NET Remoting as one of the answers, they throw in a side comment like: “although it is an obsolete technology,” or “even though you aren’t supposed to use that anymore,” or “with WCF coming out I believe web services are the preferred method.”

Having played with both .NET Remoting *and* WCF, I fundamentally disagreed with the candidates. I think there is a pretty easy upgrade path between the two. So I set out to prove:

  1. Which technology would be easier to upgrade to WCF?
  2. What are the guidelines that one should follow when choosing a inter-machine communications mechanism (assuming you can’t use WCF, yet)?

I was pre-biased so I guess I should mention that in case I skewed the results in some subconscious way. I felt that the answer to #1 would be a wash, and that #2 would depend solely on things like whether .NET was guaranteed to be running on both endpoints, and whether there was a firewall between the machines.

.NET Remoting

First I created a .NET Remoting solution. I used a Console application for the server, and a Windows forms application for the client, just to make sure that it wasn’t easier to upgrade one versus the other. Per best practices I split the interface into a separate class library which I referenced from both. I also stored the Remoting configuration in the app.config files for both the client and the server.  I chose the standard calculator interface, because that had about the right number of methods (according to Juval Lowy of IDesign, a good number of methods for an interface is 3-5 and if you reflect on .NET itself, that is what you will find). So my interface had the standard Add, Subtract, Multiply and Divide methods.  Once I had that working, I started changing it to use WCF, while taking careful notes of what I had to change.

First things first, I modified the interface by adding the service and operation contract attributes. The interface now looked like this (with new lines in bold):

using System;
using System.ServiceModel; 

namespace Calculator
{
    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        int Add(int n1, int n2);
        [OperationContract]
        int Subtract(int n1, int n2);
        [OperationContract]
        int Multiply(int n1, int n2);
        [OperationContract]
        double Divide(int n1, int n2);
    }
}
  Lines Changed Lines Added Lines Removed
here 0 6 0
total 0 6 0

Next on the server I had to change both the config file and the server class itself. I also had to add the ServiceModel project reference again.

using System;
using System.Runtime.Remoting;
using System.ServiceModel;

namespace Calculator
{
    class Program
    {
        static void Main(string[] args)
        {
            RemotingConfiguration.Configure("CalcServer.exe.config", true);
            ServiceHost serviceHost = new ServiceHost(typeof(CalcServer))
            serviceHost.Open();
            Console.WriteLine("Calculator running (press any key to close)");
            Console.ReadKey();
        }
    }
}

The line that actually fetches the configuration information changed from Configure to a line starting the host, something that was implied before.

  Lines Changed Lines Added Lines Removed
here 2 1 0
total 6 7 0

In the server config file the damage was:

<configuration>
  <system.runtime.remoting>
  <system.serviceModel>
    <application name="CalcServer">
    <services>
      <wellknown mode="SingleCall" objectUri="Calc" 
        type="Calculator.CalcServer, CalcServer" />
      <service name="Calculator.CalcServer">
        <endpoint address="net.tcp://localhost:123/CalcServer/Calc"
                  binding="netTcpBinding"
                  contract="Calculator.ICalculator" />
      </service>
      <channels>
        <channel ref="tcp server" port="123" />
      </channels>
    </application>
    </services>
  </system.runtime.remoting>
  </system.serviceModel>
</configuration>

Notice the near 1-1 mapping.

system.runtime.remoting -> system.serviceModel

application -> services

wellknown[@type] -> service[@name]

channel -> endpoint

Actually wellknown and channel morphed into a concept of service and endpoint.  WellKnown is really representing the type of the service being hosted, as is service.  But it includes two other pieces of information: the “mode”, which is described in WCF using a behavior, and the objectUri which is shifted into part of the endpoint address in WCF.  Channel describes the rest of the features present on the endpoint element.  This was a tricky one to count, and I guess this is were my biases come into play.   Because the lines were semantically the same I counted them as changes per the transforms listed above, the add of an end service tag, and the removal of the begin and end channel tags.

  Lines Changed Lines Added Lines Removed
here 6 1 2
total 12 8 2

One more line of code should change on the server side.
The CalcServer object itself also no longer needs to derive from MarshalByRefObject.

public class CalcServer : MarshalByRefObject, ICalculator

This brings the totals to:

  Lines Changed Lines Added Lines Removed
here 1 0 0
total 13 8 2

On to the client. At this point you should be getting the idea.
Almost everything in .NET Remoting has a corresponding object in WCF.

For the client we need to change the buttonAdd_Click event to look like this:

private void buttonAdd_Click(object sender, EventArgs e)
{
    double num1 = double.Parse(textBox1.Text);
    double num2 = double.Parse(textBox2.Text);

    RemotingConfiguration.Configure("CalcClient.exe.config", false);
    WellKnownClientTypeEntry[] entries = RemotingConfiguration.GetRegisteredWellKnownClientTypes();
    ICalculator calc = (ICalculator)Activator.GetObject(typeof(ICalculator), entries[0].ObjectUrl);

    ChannelFactory<ICalculator> factory = new ChannelFactory<ICalculator>("Calc");
    ICalculator calc = factory.CreateChannel();

    double result = calc.Add(num1, num2);
    textBoxResult.Text = result.ToString();
}

Two lines were changed and one was removed. Really the 3 lines in remoting were morphed into the 2 lines of WCF.

  Lines Changed Lines Added Lines Removed
here 2 0 1
total 15 8 3

The client configuration file changed almost exactly like the server one did, other than the endpoint having a name.

<configuration>
  <system.runtime.remoting>
  <system.serviceModel>
    <application name="CalcClient">
    <client>
      <endpoint name="Calc" address="net.tcp://localhost:123/CalcServer/Calc"
                binding="netTcpBinding" contract="Calculator.ICalculator" />
      <wellknown url="tcp://localhost:123/CalcServer/Calc" type="Calculator.ICalculator, CalcInterface" />
      <channels>
        <channel ref="tcp client" />
      </channels>
    </client>
    </application>
  </system.runtime.remoting>
  </system.serviceModel>
</configuration>
  Lines Changed Lines Added Lines Removed
here 4 0 4
total 19 8 7

And there we have it, so a total of (19+8+7) = 34 changes in all…

ASMX Web Services

Most people don’t really use interfaces for WebServices (although it is possible), so I will show the default (although sub-optimal) implementation.

First I need to change the attribute names:

[WebService(Namespace = "urn:brainhz:calc")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ServiceContract]
public class CalcService : System.Web.Services.WebService
{
    [WebMethod]
    [OperationContract]
    public int Add(int n1, int n2)
    {
        return n1 + n2;
    }

    [WebMethod]
    [OperationContract]
    public int Subtract(int n1, int n2)
    {
        return n1 - n2;
    }

    [WebMethod]
    [OperationContract]
    public int Multiply(int n1, int n2)
    {
        return n1 * n2;
    }

    [WebMethod]
    [OperationContract]
    public double Divide(int n1, int n2)
    {
        return (double)n1 / (double)n2;
    }
}

So the question is: does WebService or WebServiceBinding to ServiceContract count as removing and adding or a changed line?  I decided that the intent was not the same, and in fact Indigo has attributes for [ServiceBehavior] to control things like the namespaces.  Then the same question for WebMethod to OperationContract.  Here I decided that the intent was the same (opting in methods) so I counted them as changed lines.  I counted 2 lines removed, one line added and 4 lines changed.

  Lines Changed Lines Added Lines Removed
here 4 1 2
total 4 1 2

Next the config file:

<configuration>
  <system.web>
    ...
  </system.web>
  <system.serviceModel>
    <services>
      <service name="CalcService" behaviorConfiguration="mex" >
        <endpoint address=" " 
          binding="basicHttpBinding" 
          contract="CalcService"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mex">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Notice that because we don’t have an interface assembly and therefore can’t add a .NET reference to the assembly, we also have to turn on the metadata exchange in the service behavior.

  Lines Changed Lines Added Lines Removed
here 0 14 0
total 4 15 2

The last thing we need to do is remove the asmx file and replace it with a service file. This too was a tricky one to count.
Technically you are deleting and asmx file and adding a svc file, so I am going to count them as adding a line and removing a line, even though the contents of the file barely changed at all, so if the file was staying the same I might count it differently.

<%@ WebService Language="CSharp" Class="CalcService" CodeBehind="~/App_Code/CalcService.cs" %>
<%@ ServiceHost Language="CSharp" Service="CalcService" CodeBehind="~/App_Code/CalcService.cs" %>

OK so for the service that brings us to

  Lines Changed Lines Added Lines Removed
here 0 1 1
total 4 16 3

And now onto the client…

We need to remove the old reference and add a reference to the new service.  Again I will count this as an add and a remove even though hundreds of lines are changing in the background.

  Lines Changed Lines Added Lines Removed
here 0 1 1
total 4 17 4

For the client we need to change the buttonAdd_Click event to look like this:

using ClientForm.localhost;

private void buttonAdd_Click(object sender, EventArgs e)
{
    double num1 = double.Parse(textBox1.Text);
    double num2 = double.Parse(textBox2.Text);
    CalcService calc = new CalcService();
    CalcServiceClient calc = new CalcServiceClient();
    double result = calc.Add(num1, num2);
    textBoxResult.Text = result.ToString();
}
  Lines Changed Lines Added Lines Removed
here 1 0 0
total 5 17 4

Results

OK, so that brings the comparison to:

  Lines Changed Lines Added Lines Removed
Remoting 18 7 9
WebService 5 17 4

34 to 26. It appears I was wrong – WebServices were a little easier to change.

Of course if there *was* an interface, and you wanted to keep your namespace, that would have brought the totals higher by a couple of lines.

And if you were using ASP.NET features in your web service (which is probable) and you wanted to keep using those in WCF that would have added 3 more lines.
First in the config file

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

Then in code

using System.ServiceModel.Activation;

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

This would bring the totals to: 34 to 31.

This would put it in the too close to call category, especially considering counting irregularities like the fact the we regenerated web references using asmx web services.

Editorial

Ultimately it is your requirements that dictate whether you go down the .NET Remoting or the ASMX web services route, not the fact the WCF is going to release soon. The real power of WCF is its ability to support both ways of communicating rather than forcing you to pick one over the other. It is really saving you from a later requirements change like, “I know we need the speed for our internal clients but we now need to support an external client as well, and they happen to be using Java.”

Tags: , , , , ,
Posted in WCF | Comments Off