Using Transaction with WCF Services

If you need to call two different WCF service and be sure that both are successful before committing, you’ll need to use transaction. This will require that both service’s operation contain the attribute TransactionFlow with the option to Allowed. Many other option could have been possible. NotAllowed is when you do not want to be part of transaction, which is the default value. Allowed allows to participate in a transaction if the client specify in his code a transaction scope. Finally, mandatory force that the operation is called within a transaction scope.

[ServiceContract]
public interface IServiceContractOne
{
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Allowed)]
    void Method1();
}

The next step is the implementation of this contract. The method Method1() that has the TransactionFlow attribute needs to have also an attribute, this time it’s OperationBehavior.


[OperationBehavior(TransactionScopeRequired = true)]
public void Method1()
{
    //Entity Framework here
}

The method of the contract has an operation behavior that tell that it’s require to be inside a transaction scope.

The next step is to configure the web.config. It needs to have for the binding the attribute transactionflow to true.

<configuration>
  <system.serviceModel>
     <bindings>
        <wsHttpBinding>
           <binding name="MyBinding" transactionFlow="true" />
        </wsHttpBinding>
...
...

Once the binding is created, you need to use this binding.

<configuration>
 <system.serviceModel>
    <services>
      <service name="MyServiceA.Service1">
        <endpoint address="" 
                  behaviorConfiguration="behavior1" 
                  binding="wsHttpBinding"
                  bindingConfiguration="MyBinding" 
                  contract="MyServiceA.IService1" />
...
...

I have chosen wshttpbinding because to use transaction you need to use a WS-Atomic Transaction or OleTransactions protocol.

Finally, you can test the transaction by having an application that use the two services (or more) that you created with the contract that has transaction score required.

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
   try
   {
      var obj = new ServiceReference1.Service1();
      obj.Method1();
      var obj1 = new ServiceReference2.Service1();
      obj1.Method1();
      ts.Complete(); //Commit everything!
   }
   catch (Exception ex)
   {
      ts.Dispose();
   }
}

If any exception occur during the scope of the transaction, everything is rollback.

You can add additional information to the service that has method with transaction mandatory or allowed. It’s done with ServiceBehavior. You can specify the transaction time out and also the transaction isolation level. The timeout is a time that you allow for the service to be executed. The isolation level is the same as when you use transaction without services. It tells how to lock the information during the transaction. By default, it’s serializable which block everything to be changed. It’s the most protective and also the worst in term of performance. I won’t discuss about every type of isolation level but some allow you to insert new data while other allow you to simply change everything. You have to figure out which one is the correct for your needs. Do not forget to add System.Transaction reference into your project if you do want to use transaction.

[ServiceBehavior(TransactionIsolationLevel=System.Transactions.IsolationLevel.Serializable, TransactionTimeout="00:00:30")]

WCF Inspector for logging

We have already talk about how to log every call of your WCF service with a custom factory for all your WCF service. This is a good way to log or to verify access to all your service methods. The main point was to create a factory which is called every calls it’s done. Once it generated, it creates a new service behavior to which it needs to have a new operation behavior and invoker.

This time, the solution to log every method call it is by using inspector. An inspector is a filter that is executed before and after a request is executed. First of all, this solution works by configuring in the web.config a behavior. An entry to system.serviceModel > extensions > behaviorExtensions needs to be added and will be used to system.serviceModel > endpointBehaviors > behavior.

Here is an example of the web.config:

<system.serviceModel>
     <extensions>
            <behaviorExtensions>
                <add name="myLogBehavior"
                     type="MyServiceA.LogFileBehaviorExtensionElement, MyServiceA" />
            </behaviorExtensions>
        </extensions>
...
 <services>
      <service name="MyServiceA.Service1">
        <endpoint address="" 
                  behaviorConfiguration="behavior1" 
                  binding="wsHttpBinding"
                  bindingConfiguration="" 
                  contract="MyServiceA.IService1" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
          <behavior name="behavior1">
              <myLogBehavior logFileName="c:\log.txt" />
          </behavior>
      </endpointBehaviors>

...

Three parts are important. The first one is the extension that define the behavior extension. This allow us to create configuration outside the code that is defined inside the web.config. A name is specify that is referred later inside the web.config, and the second attribute is the name of the extension inside the code. In the example above, the code display a LogFileBehaviorExtensionElement that is inside the MyServiceA namespace. The second part is the service’s endpoint itself. This is where we specify the contract, the binding and also the behaviorConfiguration. This behavior configuration lead us to the third important part which is the behavior that we have created. The third part is the endpointBehaviors where it specify the behavior. In the example, it’s named “behavior1” which is referenced inside the endpoint. Inside this third part, the myLogBehavior define a parameter where it’s the file log name.

The next step is to create the behavior extension element inside the code.

/// <summary>
/// Allow to join the end point behavior via web.config + parameter for the web.config
/// </summary>
public class LogFileBehaviorExtensionElement : BehaviorExtensionElement
{
    [ConfigurationProperty("logFileName")]
    public string LogFileName
    {
        get
        {
            return (string)base["logFileName"];
        }
        set
        {
            base["logFileName"] = value;
        }
    }

    protected override object CreateBehavior()
    {
        return new LogOutputBehavior(this.LogFileName);
    }

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

As you can see, this contain a configuration property which is the attribute of the file name defined in the web.config. It also create the behavior. The next class to create is the endpoint behavior. This is where we add the inspector to the endpoint. This mean that every method of the service will have the inspector hooked to them. If it’s not the desired behavior, it’s also possible to hook an inspector with a custom attribute.

/// <summary>
/// Allow to hook an inspector
/// </summary>
public class LogOutputBehavior : IEndpointBehavior
{
    private string logFileName;
    public LogOutputBehavior(string logFileName)
    {
        this.logFileName = logFileName;
    }

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

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

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        LogOutputMessageInspector inspector = new LogOutputMessageInspector(this.logFileName);
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
}

The behavior create the inspector.

/// <summary>
/// The inspector
/// </summary>
public class LogOutputMessageInspector : IDispatchMessageInspector
{
    private string logFileName;
    public LogOutputMessageInspector(string logFileName)
    {
        this.logFileName = logFileName;
    }
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
        request = buffer.CreateMessage();
        File.AppendAllText(this.logFileName, "["+DateTime.Now+"] Request : " + request.ToString());
        return null;
    }
    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
        reply = buffer.CreateMessage();
        File.AppendAllText(this.logFileName, "[" + DateTime.Now + "] Reply : " + reply.ToString());
    }

}

This is the inspector! We have the AfterReceiveRequest, that is called just before the method of the controller in entered and the BeforeSendReply that is called after the method is called. This Allow you to create an entry in the log and to know the starting and ending time of the call. You can also have access to the message sent. This is in soap format. Here is an example:

[2013-11-09 14:21:01] Reply : 
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://tempuri.org/IService1/GetDataResponse</a:Action>
    <a:RelatesTo>urn:uuid:af68f512-6948-4c2f-b0a8-36cbd9799ebf</a:RelatesTo>
  </s:Header>
  <s:Body>
    <GetDataResponse xmlns="http://tempuri.org/">
      <GetDataResult>You entered: 0</GetDataResult>
    </GetDataResponse>
  </s:Body>
</s:Envelope>

You have all the information you want. In real, you would like to parse this xml to get the method name which is inside the envelope>header>action or by using the Message property Headers and use the Action property to get the method called. It’s also possible to get HttpRequest information is the endpoint is an http one.

MessageWithHttpRequest

This is it for WCF inspector.

WCF Data Services is the implementation of OData by Microsoft

Several time a week I hear confusion concerning WCF services, WCF Data Services, ADO Data Service and OData. First of all, ADO Data Service is out. In fact, it’s the old name for WCF Data Service which is the good sentence for OData by Microsoft. WCF service focus on contract when Data Service focus more on the data. OData is been invented by Microsoft but is not the implementation in .Net. It’s the protocol which is open.

WCF Data Service is a type of service that provide information through url. This is easily consumable because it requires only a web browser to execute a call which can have filter, join between entities and conditions. WCF Data Service uses the entity-relationship conventions of the Entity Data Model to expose resources as sets of entities that are related by associations. Not only can you get information the way you want but you can also update entity and insert.

WCF Data Service lets you use two well know structured semantic which is Atom (XML) and JSON. Both of these protocole are RestFul. That mean that when a call is executed, the life cycle end once the data is sent back to the consumer.

To create a WCF Data Service, simply create a class that inherit from DataService. It’s a generic class so you will have to specify a DataContext type. To use this class, you need to reference the dll : System.Data.Services.

public partial class MyService: DataService<MyDbContext>
{
   //...
}

You will have to also specify which entities is allowed to be accessed in InitializeService.

public static void InitializeService(DataServiceConfiguration config)
{
   //...
}

The simplicity lets you add this service in a later stage of your project. It’s even more true if your project is already using Entity Framework because OData is tightly coupled Entity Framework way to handle entity. This is why it’s very easy to create a WCF Data Service with Entity Framework because of the Data Model that both share.

OData is between the consumer and the source, the consumer could be a simple web browser and the source a .Net application or SQL Azure server. This is very powerful because you can make a mobile application that use the same service as a web site or a winform. Even more, you can create on different web browser (Internet Explorer, FireFox, Chrome) or different mobile platform (Android, IPhone, Windows Phone) with the same WCF Data Service.

The OData protocol lets you send more than only GET request. GET http request will only give you the possibility to receive data. In the case you want to delete data, a DELETE http request would be required. POST is used to insert, PUT to update. The protocol uses string and not a reference, this is why XML and JSON is used. It also respect the concept of not being tight to the server by being RestFul. So in short, a SQL table (rows) is converted into Entity Set (entity) which is converted to a collection of entry (entry).

WCF Data Services also supports data models that are based on common language runtime (CLR) objects that return an instance of the IQueryable interface.

How to use log every call of your WCF service’s methods

If you want to log information like which method has been called with which parameters on every methods of your WCF service, you shouldn’t set the log every time on each method. Two approaches is possible to create something clean.

The first option is to create an attribute and when this one is present will log. The second is to automatically log every call. I’ll show you the second approach since it’s seem more logic to log every methods. If you are curious about how to do it with an attribute, I’ll post in few times the code to apply security with WCF with attribute which will show you how to do it.

This article shows you how to log every calls of WCF’s methods. It will use Unity as IOC. So, this article show you how to use an IOC (Unity) with WCF also.

The first step is to modify your service definition. This can be done by editing the .scv (not the .svc.cs).

<%@ ServiceHost Language="C#" 
Debug="true" 
Service="MyNameSpace.MyServices.MyService" 
CodeBehind="MyService.svc.cs" 
Factory="MyNameSpace.MyServices.Common.MyServiceHostFactory " %>

The important modification is the Factory attribute. This one is required to be able to use Unity. This act as the global.asax.cs. By this, I mean, it’s called when the service is initialized and not at every calls. Behind this factory, you own class is instanced and you are able to return your own ServiceHost class. This is a door to initialize Unity (IoC), AutoMapper and many others utilities class that need to be instanced once.

public class MyServiceHostFactory : ServiceHostFactory
{
	protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
	{
		var serviceHost = new MyServiceHost(serviceType, baseAddresses);
		//ConfigureUnity(serviceHost.Container);
		//ConfigureAutoMapper();
		return serviceHost;
	}
}

The MyServiceHostFactory creates a MyServiceHost and configure the inversion of control container. It also initialize the Automapper configuration. The MyServiceHost inherit from ServiceHost, which let you add the implementation of the IoC container and handle behaviors. To be able to log on every service’s method, a new behavior need to be defined.

public class MyServiceHost : ServiceHost
{
	public UnityContainer Container { get; set; }
	
	public MyServiceHost()
	{
		Container = new UnityContainer();
	}

	public MyServiceHost(Type serviceType, params Uri[] baseAddresses): base(serviceType, baseAddresses)
	{
		Container = new UnityContainer();
	}

	protected override void OnOpening()
	{
		base.OnOpening();

		if (this.Description.Behaviors.Find<MyServiceBehavior>() == null)
		{
			this.Description.Behaviors.Add(new MyServiceBehavior(Container));
		}
	}
}

The MyServiceHost initializes the container and add a single behavior which handle the logging feature.

public class MyServiceBehavior : IServiceBehavior
{
	public UnityInstanceProvider InstanceProvider { get; set; }

	public MyServiceBehavior()
	{
		InstanceProvider = new UnityInstanceProvider();
	}

	public MyServiceBehavior(UnityContainer unity)
	{
		InstanceProvider = new UnityInstanceProvider {Container = unity};
	}

	public void AddBindingParameters(ServiceDescription serviceDescription, 
									ServiceHostBase serviceHostBase, 
									Collection<ServiceEndpoint> endpoints,
									BindingParameterCollection bindingParameters)
	{	
	}

	public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
	{
                InstanceProvider.ServiceType = serviceDescription.ServiceType;
		foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
		{
			var cd = cdb as ChannelDispatcher;
			if (cd != null)
			{
				foreach (EndpointDispatcher ed in cd.Endpoints)
				{
					ed.DispatchRuntime.InstanceProvider = InstanceProvider;
				}
			}
		}

		var log = InstanceProvider.Container.Resolve<ILog>();
		IOperationBehavior behavior = new LoggingOperationBehavior(log);
		foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
		{
			foreach (OperationDescription operation in endpoint.Contract.Operations)
			{
				if (!operation.Behaviors.Any(d => d is LoggingOperationBehavior))
				{
					operation.Behaviors.Add(behavior);
				}
			}
		}
	}

	public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
	{ 
	}
}

This is where we attach for all endpoints, all operations (methods) the behavior to be executed. This is where we add the logging behavior. The first foreach is required for Unity to be the provider while the second foreach is there to add the logging behavior.

public class UnityInstanceProvider : IInstanceProvider
    {
        public IUnityContainer Container { set; get; }
        public Type ServiceType { set; get; }


        public UnityInstanceProvider()
            : this(null)
        {
        }

        public UnityInstanceProvider(Type type)
        {
            ServiceType = type;
            Container = new UnityContainer();
        }

        public object GetInstance(InstanceContext instanceContext, Message message)
        {
            return Container.Resolve(ServiceType);
        }

        public object GetInstance(System.ServiceModel.InstanceContext instanceContext)
        {
            return GetInstance(instanceContext, null);
        }

        public void ReleaseInstance(InstanceContext instanceContext, object instance)
        {

            var myInstance = instance as IDisposable;

            if (myInstance != null)
            {
                myInstance.Dispose();
            }
        }
    }
public class LoggingOperationBehavior : IOperationBehavior
{
	private readonly ILog _myLog;

	public LoggingOperationBehavior(ILog myLog)
	{
		_myLog = myLog;
	}

	public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
	{
		dispatchOperation.Invoker = new LoggingOperationInvoker(_myLog, dispatchOperation.Invoker, dispatchOperation);
	}
	
	public void Validate(OperationDescription operationDescription)
	{
	}
	
	public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
	{
	}

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

At this point, we need to invoke the log. We need to specify an invoker that will be executed. This is why, we need to create a logging invoker which take the log that come from Unity.

public class LoggingOperationInvoker : IOperationInvoker
{
	private readonly IOperationInvoker _baseInvoker;
	private readonly string _operationName;
        private readonly string _controllerName;
	private readonly ILog _myLog;

	public LoggingOperationInvoker(ILog myLog, IOperationInvoker baseInvoker, DispatchOperation operation)
	{
		_myLog = myLog;
		_baseInvoker = baseInvoker;
		_operationName = operation.Name;
                _controllerName = operation.Parent.Type==null?"[None]":operation.Parent.Type.FullName;
	}
	
	public object Invoke(object instance, object[] inputs, out object[] outputs)
	{
		_myLog.Log("Method " + _operationName + " of class " + _controllerName + " called");
		try
		{
			return _baseInvoker.Invoke(instance, inputs, out outputs);
		}
		catch (Exception ex)
		{
			_myLog.Log(ex);
			throw;
		}
	}

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

	public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
	{
		_myLog.Log("Method " + _operationName + " of class " + _controllerName + " called");
		return _baseInvoker.InvokeBegin(instance, inputs, callback, state);
	}

	public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)	{return _baseInvoker.InvokeEnd(instance, out outputs, result);	}

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

This is where the log is really written. It uses the interface to log which came from Unity from the Factory. The log is written when the method is invoked.