Create and host a WCF service in SharePoint 2010

Recently, I came across a scenario where I had to hit sharepoint using client object model to query data from the entire site collection. Most of you must be aware that Client object model doesn’t provide an API that can query data from all the lists in a site collection. Therefore, I had to create a WCF service in Sharepoint which used SharePoint server object model. I basically used SPSiteDataQuery object.

Creating and hosting a WCF service is not a rocket science at all. Well, atleast not in SharePoint.

In this blog, I will create a very simple WCF Service just to get familiar with the process and host it in sharepoint. This webservice will simply return the title of the sharepoint site.

Lets get started.

Step 1- Create implementation logic

In Visual studio project, create a Class Library project. 

  • In your project, add references to the System.Runtime.Serialization and System.ServiceModel WCF assemblies, and also to Microsoft.SharePoint. Right-click the project, click Add Reference, and select each of these assemblies on the .NET tab.
  • Also, add a reference to Microsoft.SharePoint.Client.ServerRuntime, which contains the service factories that are provided by SharePoint Foundation, use the Browse tab of the Add Reference box to navigate to the Microsoft.SharePoint.Client.ServerRuntime.dll file in %Windows%\assembly\GAC_MSIL\Microsoft.SharePoint.Client.ServerRuntime, select the DLL, and then click OK.

Add an interface with the following code. This exposes a simple method which returns the title of the sharepoint site.

namespace Manvir.SharePoint.WCFService
{
      using System.Data;
      using System.ServiceModel;
      using System.ServiceModel.Web;
      [ServiceContract(Name = “CustomService”)]
      interface ICustomService
      {
        [OperationContract]
        [WebInvoke(Method = “POST”, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        string GetWebTitle();
      }
}

Create a class which specify the implementation of the service.

namespace Manvir.SharePoint.WCFService
{
    using System;
    using System.Data;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Client.Services;

    [ServiceBehavior(Name = “CustomService”)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [BasicHttpBindingServiceMetadataExchangeEndpoint]
    public class CustomService : ICustomService
    {
        public string GetWebTitle()
        {
            try
            {
               return SPContext.Current.Web.Title;   
            }
            catch (Exception ex)
            {
                throw new FaultException(“Exception thrown by Custom service:” + ex.Message);
            }
        }
    }
}

Here note the usage of ‘FaultException’. The service can’t return a .Net exception to the client. The WCF service and client communicate by passing SOAP messages. When I throw a FaultException in my code, WCF catches FaultException and generates a fault message that will be sent to the client.

Please note that you can handle exceptions in WCF service more gracefully than I have shown. For detailed exception handling, visit this link http://msdn.microsoft.com/en-us/library/ee942778.aspx

Now that the implementation of the service is ready, you need to create a corresponding registration file(.svc) in sharepoint.

STEP 2 – Create a registration file(.svc) in SharePoint

To create registration file for our service in the ISAPI folder-

1) Right click on the sharepoint project, point to ‘Add’, and click ‘SharePoint Mapped Folder’. In the dialog box, select ISAPI and then click Ok.This will add ISAPI folder in sharepoint project which is mapped to the 14hive/Isapi folder in sharepoint system directory.

2) Add any text file to ISAPI folder in project and rename it to ‘CustomService.svc’. Add the following declaration to CustomService.svc.

<%@ ServiceHost Language=”C#” Debug=”true” Factory=”Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory”
Service=”Manvir.SharePoint.WCFService.CustomService” %>
<%@ Assembly Name=”Manvir.SharePoint.WCFService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3494d637122aa84b” %><%@ Assembly Name=”Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

Because Visual Studio 2010 by default does not process the type of tokens used in the previous .svc file, you must add an additional instruction in the project file.Save all changes in your project. Open your project file i.e. .csproj(or .vbproj) in notepad and add a <TokenReplacementFileExtensions> tag as follows to the first property group in the .csproj or .vbproj file. It should something like this.

<?xml version=”1.0″ encoding=”utf-8″?>
<Project ToolsVersion=”4.0″ DefaultTargets=”Build” xmlns=”http://schemas.microsoft.com/developer/msbuild/2003“>
  <PropertyGroup>
    <Configuration Condition=” ‘$(Configuration)’ == ” “>Debug</Configuration>
    <Platform Condition=” ‘$(Platform)’ == ” “>AnyCPU</Platform>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{F455078E-8836-403A-9E63-5E5F21B5F694}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>CustomService</RootNamespace>
    <AssemblyName>CustomService</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{BB1F664B-9266-4fd6-B973-E1E44974B511};{14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <SandboxedSolution>False</SandboxedSolution>
<TokenReplacementFileExtensions>svc</TokenReplacementFileExtensions>
  </PropertyGroup>

Deploy your sharepoint solution and thats it! To make sure that it is up and running, verify by typing this url in any browser –

http://[replaceitwithursharepointsiteurl]/_vti_bin/Customservice.svc

Step 3 – Consume WCF service

To consume this WCF service, use this code in any of the client application whether its windows application, console application or other web service after adding service reference to the url http://[yoursharepointsite]/_vti_bin/Customservice.svc
try
{
      BasicHttpBinding binding = new BasicHttpBinding();
      binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
      binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
      EndpointAddress endpoint = new EndpointAddress(“http://blahblah/_vti_bin/CustomService.svc”);
      CustomServiceClient proxy = new CustomServiceClient(binding, endpoint);
      proxy.ClientCredentials.Windows.AllowedImpersonationLevel =    System.Security.Principal.TokenImpersonationLevel.Impersonation;

     string title = proxy.GetWebTitle();
}
catch(FaultException ex)
{
// Catch and act accordingly.
}

Leave a Comment

Your email address will not be published. Required fields are marked *