Recently I have been working with Windows Communication Foundation (WCF) Service in SharePoint 2010. We built a jQuery AJAX heavy web application on top of the SharePoint platform, with business data exposed from a custom Microsoft SQL database. The solution should be accessed from within a SharePoint intranet site and within its security boundaries and SharePoint groups. Based on those requirements we chose WCF Service as communication architecture to expose the object model and the business objects.

WCF configuration

Windows Communication Foundation (WCF) is a unifying programming model for creating service oriented applications, that supports many hosting options and communications protocols. The technology may seem complex in terms of all the configuration possibilities. For this solution we have used a WCF JSON enabled REST service, which is a service configured to use the HTTP protocol. The requests and responses are text based (not SOAP) and the formatting is JSON. The serializing and deserializing of objects on both sides of the service is taken care of by the service, simply passing JavaScript objects on frontend and .NET objects on backend.

To set up a SharePoint project with WCF service some dll references needs to be added manually: System.ServiceModel, System ServiceModel.Web and System.Runtime.Serialization. To expose the service to run inside the SharePoint project an ISAPI mapped folder is added to the solution with a service file (.svc). This is a text file that contains information about the service that can be run using Microsoft Internet Information Services.

The svc file point to the implementation of the service:

<span style="color: #808080;">&lt;%@ ServiceHost Language="C#" Debug="true" Service="Myservice.Service,Myservice, Version=1.0.0.0,Culture=neutral, PublicKeyToken=a0b806fa45919e70" %&gt;</span>

The service is defined by a service contract which is an interface class defining data and operations, and a service class which implements the contract. The service is a wrapper for business logic class which processes the requests and responses, and the data layer which accesses the database.

The configuration of the service is set up in web.config file:

<span style="color: #808080;">&lt;system.serviceModel&gt; &lt;serviceHostingEnvironment aspNetCompatibilityEnabled="true"/&gt; &lt;!-- Behavior setting for wcf  service --&gt; &lt;behaviors&gt; &lt;endpointBehaviors&gt; &lt;!-- configuration for rest relies on web http --&gt; &lt;behavior name="RestBehavior"&gt; &lt;webHttp /&gt; &lt;/behavior&gt; &lt;/endpointBehaviors&gt; &lt;/behaviors&gt; &lt;services&gt; &lt;!-- register wcf service --&gt; &lt;service name="Myservice.Service"&gt; &lt;endpoint address="" binding="webHttpBinding" behaviorConfiguration="RestBehavior" contract="Myservice.IService" bindingConfiguration="WindowsAuthenticationBasicHttpBinding"&gt; &lt;/endpoint&gt; &lt;/service&gt; &lt;/services&gt; &lt;bindings&gt; &lt;!-- webhttp binding for service--&gt; &lt;webHttpBinding&gt; &lt;binding name="WindowsAuthenticationBasicHttpBinding"&gt; &lt;security mode="TransportCredentialOnly"&gt; &lt;transport clientCredentialType="Windows" /&gt; &lt;/security&gt; &lt;/binding&gt; &lt;/webHttpBinding&gt; &lt;/bindings&gt; &lt;/system.serviceModel&gt;</span>

<serviceHostingEnvironment aspNetCompatibilityEnabled=”true” />
Setting this value to true indicates that all WCF services running in the application run in ASP.NET Compatibility Mode. In WCF, a binding determines how WCF is going to communicate. For a RESTful endpoint, the binding is set to <WebHttpBinding>.  An endpoint behavior for the service is set to to enable the web programming model for WCF.

The communication channel for WCF is HTTP instead of SOAP, configured by <webHttpBinding> as binding configuration. This channel is configured with security on the transport channel, using windows credentials (which would be integrated SharePoint authentication). Note that clientCredentialType is set to “Windows”. Another option is “Ntlm”, but when Kerberos is used as authentication provider, only “Windows” would work.

The service itself is configured in the configuration with the service interface contract and the mapping to the binding endpoints and behaviors.

WCF implementation

The WCF service is defined with a service contact which specifies the operations the client can perform on the service.

[ServiceContract] public interface IService { [OperationContract] [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)] String HelloWorld(string Message); }

To pass a custom object as request or response specify a DataContract that agree on the exchange format. The datamembers must be serializable:

[DataContract] public class Tag { [DataMember] public Int32 TagID{ get; set; } [DataMember] public string KeyT { get; set; } }

The service class implementation:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class Service : IService { ... }

Security and permissions

The application is hosted in a SharePoint site and uses SharePoint authentication. The WCF service is also configured to use the same security provider. To expose different functionality to different user groups, a set of SharePoint groups was created.  The access level is implemented both on fronted and backend, authenticating user against the specified groups. The service call itself is not doing the access check, except from the authentication. The business layer checks what access level the current user has and returns appropriate data. This is possible beacuse the service is running with the current user credentials.  It is also possible to configure permissions levels on the WCF itself by using role based security. This would be easy to setup for AD user groups,  but I’m not sure how it would work for SharePoint groups.

Testing WCF services

The code in the service itself is very simple; it does almost nothing because it is an interface and external point to the application. A service could do data validation and the main action is to transfer objects to call methods on the business model. But since the service contains code it is still prone to have defects and bugs like other parts of the application. Therefor it must be a good idea to do some validation and verification to ensure proper quality. And the idea was to do unit testing and to use Test Driven Development (TDD). But to make a WCF service testable and take advantage of TDD, the code has to be refactored to accept dependencies.

What made unit testing so difficult to start with is that the service has dependencies on the business and data access layers. When testing relies on resources like database it becomes unstable and hard to debug as there are dependencies through different layers.  In addition there were dependencies to SharePoint framework as well. This would result in an another type of test called integration test. So I ended up implementing an integration test even that was not the intention when I started. They are still a good value as you could test the overall system. But I experienced it to be very fragile and hard to detect errors because it would go through several layers and paths on system. There were also problems running the tests when the system was  depending on sharepoint authentication.

A unit test should test only one single specified requirement of the system.  I started looking at Pex and Moles framework for unit testing. There are other testing and mock frameworks like NUnit and Moq, but I needed a framework that is able to also mock SharePoint libraries. So I could do testing for the buisness and database layers. But I did not have time to do it properly because of the dependency injection learning curve. I have studied an example of using Ninject for WCF dependency injection, so maybe I will do a post on it later when I have tested it out.

The frontend

The frontend was implemented with Knockout,  a JavaScript MVVM inspired framework for separating view from model. Maybe another post on that later..  As a developer tool it is simply great. It uses JQuery data binding and templates to build rich and responsive user interfaces. We also did some unit testing on the frontend using QUnit framework. This part of the application was not my main responsibility, but was developed by one of my great colleagues :)