Step by Step – Building and Consuming Custom WCF Services hosted in SharePoint

Note: Download Code discussed in this article from Here

If you are developing enterprise level custom solutions based on SharePoint framework, you would come across scenarios where you have to expose and access SharePoint data from remote applications like CRM, ASP.NET, Silverlight, or other SharePoint applications. SharePoint 2010 Out of box allows multiple ways to interact with SharePoint data from remote applications like Client Object Model, REST based API, ASP.NET SOAP web services etc. As we all come across, these options are not sufficient in real world scenarios and it would require writing custom WCF Services.

As you can read from earlier article, one of the great things about WCF services are they can be hosted and deployed multiple ways. One of the options are SharePoint 2010 allows custom WCF service hosted in SharePoint Root ISAPI directory. In this article, I will walkthrough step by step process of setting up custom WCF service project as SharePoint Solution, how it can be deployed to the SharePoint 2010, and how it can be consumed from the SharePoint web parts.

The Custom WCF Service built in this article returns list of documents name and title information from the Shared Document Library in the root site collection web site and displays on the SharePoint Site using web parts interface.

Step 1 => Setup WCF Service Project to host in SharePoint

Create New Empty SharePoint Project – Niks.SP2010.SPHostedWCFService and Select “Deploy as a Farm Solution”. This approach will deploy WCF service in SharePoint Root, ISAPI directory.

Add WCF Service Project Item by right clicking on Project and Add New Item.

From the Add New Item window, select C# and select WCF Service. Specify SPHostedWCFService.cs and Add item to the project.

This should add three files in the project – web.config, ISPHostedWCFService.cs, and SPHostedWCFService.cs. Please note that ISPHostedWCFService is service interface and SPHostedWCFService is class implementation.

App.config should look like this.

<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Niks.SP2010.SPHostedWCFService.SPHostedWCFServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="Niks.SP2010.SPHostedWCFService.SPHostedWCFServiceBehavior"
name="Niks.SP2010.SPHostedWCFService.SPHostedWCFService">
<endpoint address="" binding="wsHttpBinding" contract="Niks.SP2010.SPHostedWCFService.ISPHostedWCFService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="<a href="http://localhost:8732/Design_Time_Addresses/Niks.SP2010.SPHostedWCFService/SPHostedWCFService/">http://localhost:8732/Design_Time_Addresses/Niks.SP2010.SPHostedWCFService/SPHostedWCFService/</a>" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>

Next step is to compile the Project and find the PublicKeyToken using sn.exe from command prompt. This is required for next steps for full assembly reference in WCF Service file. Running this command prompt, would return public key token – 9a823b7ed0a910a2 for this WCF Web Service

Unfortunately there is no “WCF Service” SharePoint Project Item available in Visual Studio. You can download CKSDEV codeplex solution which would ease adding WCF Service SPI in Visual Studio.

Since I wanted to go with manual way (which is easy by the way), To host WCF Service in SharePoint ISAPI folder, right click on project and Add SharePoint Mapped folder – ISAPI. Within ISAPI folder, add SPHostedWCFService folder to host custom WCF web service and add two text files and rename them as SPHostedWCFService.svc and web.config

Add following lines in SPHostedWCFService.svc, Specify correct PublicKeyToken derived from earliar step.

<%@ Assembly Name="Niks.SP2010.SPHostedWCFService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9a823b7ed0a910a2"%>
<%@ ServiceHost Service="Niks.SP2010.SPHostedWCFService.SPHostedWCFService" %>

Add following in web.config in ISAPI folder

<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<bindings>
<basicHttpBinding>
<binding name="customBasicHttpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="customBasicBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="customBasicBehavior"
name="Niks.SP2010.SPHostedWCFService.SPHostedWCFService">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="customBasicHttpBinding"
contract="Niks.SP2010.SPHostedWCFService.ISPHostedWCFService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="<a href="http://localhost/_layouts/WorkflowDemonstration">http://localhost/_layouts/WorkflowDemonstration</a>" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>


Step 2 => Implement Business Logic in WCF Service

Once basic project is setup, next logical step would be implementing business logic in WCF Service. Each WCF Service has to define two steps – Interface and Implementation.

Define the Service Contract and Data Contract in ISPHostedWCFService.cs

[ServiceContract]
public interface ISPHostedWCFService
{
[OperationContract]
List<DocumentData> GetLists();
}

[DataContract]
public class DocumentData
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Title { get; set; }
}

Implement the Service Contract – SPHostedWCFService.cs

In this WCF Service, since I am hosting WCF Service on the SharePoint farm, I am using Server Side Object Model to access Shared Documents document library from the root site collection web site and return documents information in the business object collection.

Since SharePoint is ASP.NET web application, please ensure to set each service method – AspNetCompatibilityRequirements to either Required or Allowed for ASP.NET compatability as shown in following code snippet.

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SPHostedWCFService : ISPHostedWCFService
{
public List<DocumentData> GetLists()
{
List<DocumentData> docData = new List<DocumentData>();

string siteURL = "<a href="http://sp2010vm/">http://sp2010vm</a>";
string documentListName = "Shared Documents";

using (SPSite spSite = new SPSite(siteURL))
{
SPDocumentLibrary spLibrary = (SPDocumentLibrary)spSite.RootWeb.Lists.TryGetList(documentListName);
foreach (SPListItem listitem in spLibrary.Items)
{
docData.Add(new DocumentData() { Name = listitem.Name, Title = listitem.Title});
}
}

return docData;
}
}

Step 3 => Deploy WCF Service in SharePoint

Once WCF Service logic is implemented, next logical step is to package the WCF service solution and deploy it to the SharePoint. This step is similar to any other SharePoint WSPs. This step requires packaging WCF SharePoint solution and deploys it through Visual Studio or Solutions & Features Framework API as Farm level solution. Deploying solution would provision Niks.SP2010.SPHostedWCFService.dll into GAC and Niks.SP2010.SPHostedWCFService folder wtih WCF endpoint in SharePoint Root ISAPI directory.

To Test the WCF Service Interface, Click on the URL – http://SP2010VM/_vti_bin/SPHostedWCFService/SPHostedWCFService.svc

If your SharePoint Web Application IIS web site is not enabled for anonymous authentication or claims based authentication, it would ask you for the credential. Click on the Link – http://sp2010vm.niks.local/_vti_bin/SPHostedWCFService/SPHostedWCFService.svc?wsdl to see the service contract information.

Step 4 => Consume WCF Service from SharePoint

In real world scenarios, you would be consuming WCF services from the non-SharePoint remote applications like CRM, SQL Server SSIS Packages, ASP.NET, Silverlight, or Console Utilities. For the demonstration purpose, I will consume Custom WCF Service from the SharePoint web application.Create new empty SharePoint Project – Niks.SP2010.SPHostedWCFServiceClient

Reference the WCF Service by right clicking project and Add Service Reference. Enter WCF Service Address  – http://SP2010VM/_vti_bin/SPHostedWCFService/SPHostedWCFService.svc and and Click Go to discover. Add Proper Namespace and click OK to add WCF Service Proxy in Visual Studio

Adding reference to the WCF Service, would add app.config file in the project which needs to be copied to the SharePoint Web Application Web.Config file. To Consume WCF Service from SharePoint User Inteface, Add Visual Web Part

In Visual Web Part Code, invoke the WCF Service proxy, pass the user credential to the service, and call service method to return list of documents by populating ASP.NET data grid. Following code would invoke service and run WCF Service under user context.

protected void Page_Load(object sender, EventArgs e)
{
Niks.SP2010.SPHostedWCFServiceClient.SPHostedWCFService.SPHostedWCFServiceClient client
= new Niks.SP2010.SPHostedWCFServiceClient.SPHostedWCFService.SPHostedWCFServiceClient();
client.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;

Niks.SP2010.SPHostedWCFServiceClient.SPHostedWCFService.DocumentData[] docData = client.GetLists();
gvDocData.DataSource = docData;
gvDocData.DataBind();
client.Close();
}

Final step to call WCF Service properly during runtime, Copy App.Config <System.ServiceModel> section to the SharePoint Web Application. By default, it’s using basicHttpBinding binding & NTLM as authentication method. Please note that WCF Service endpoint is ttp://sp2010vm.niks.local/_vti_bin/SPHostedWCFService/SPHostedWCFService.svc.

<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ISPHostedWCFService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="<a href="http://sp2010vm.niks.local/_vti_bin/SPHostedWCFService/SPHostedWCFService.svc">http://sp2010vm.niks.local/_vti_bin/SPHostedWCFService/SPHostedWCFService.svc</a>"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISPHostedWCFService"
contract="SPHostedWCFService.ISPHostedWCFService" name="BasicHttpBinding_ISPHostedWCFService" />
</client>
</system.serviceModel>
</configuration>

Once web.config is properly configured, open the SharePoint Web Application and add Custom Web Part on the page. It should display list of all the documents name & title in Grid View

Important Notes regarding Updating WCF Service Interface & Implementation

  • If you are changing any logic in WCF Service contract implementation, you don’t have to refresh Service Reference from the Client.
  • If you have changed WCF Service Contract Interface or Business Objects Definitions, you don’t have to refresh Service Reference from the Client using Visual Studio

Additional References – Hosting WCF Services in SharePoint

Advertisements
This entry was posted in SP2010 DEV General. Bookmark the permalink.

One Response to Step by Step – Building and Consuming Custom WCF Services hosted in SharePoint

  1. Pingback: After Install CKSDEV I don´t see the WCF Service (CKSDev) « Letras y Números

Comments are closed.