This post is about how to create a WCF Service and host it in SharePoint Foundation (or up) using the available Service Factory. I use CKSDev for these steps, but you can also use standard Visual Studio tools to accomplish the same results. CKSDev just takes care of all the initial plumbing and is a real timesaver. There are quite a few articles and posts out there, that describe this very process, but I like to keep this as a personal note. As a bonus I will be cleaning out the dreadful http://tempuri.org namespaces!
Overview:
1. Create WCF Service based on CKSDev template
2. Deploy to SharePoint
3. Change the http://tempuri.org namespaces
Create a WCF Service and deploy to SharePoint
1. Create a new solution and project.
Template: Empty SharePoint Project
Target: .NET Framework 3.5
2. Deploy it as a farm solution, since the assembly should go in the GAC.
Image may be NSFW.
Clik here to view.
3. Add a new item to the empty SharePoint project:
WCF Service (CKSDev)
Image may be NSFW.
Clik here to view.
4. This will create the following structure for you:
Image may be NSFW.
Clik here to view.
IHostedWCFService.cs | Interface and WCF Service Contract |
HostedWCFService.svc.cs | WCF Service Class |
HostedWCFService.svc | WCF Service declaration |
5. Build and deploy
6. Access the Service using the browser. To be able to do this, you will need to access the service using the MEX endpoint (see note). Just append “/mex” to the service url in your browser.
Image may be NSFW.
Clik here to view.
Next steps: change the http://tempuri.org namespaces
First we remove the one in the WCF Service Implementation (corresponds to the wsdl definition targetnamespace)
<wsdl:definitions name="HostedWCFService" targetNamespace="http://tempuri.org/" />
1. Add a using System.ServiceModel;
2. Decorate the implementation class with a ServiceBehavior attribute
namespace Blog.Examples.HostWCF { [BasicHttpBindingServiceMetadataExchangeEndpoint] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] [ServiceBehavior(Namespace = "http://schema.demo.loc/HostWCF")] public class HostedWCFService : IHostedWCFService { // To test this service, use the Visual Studio WCF Test client // set the endpoint to http://<Your server name>/_vti_bin/Blog.Examples.HostWCF/HostedWCFService.svc/mex public string HelloWorld() { return "Hello World from WCF and SharePoint 2010"; } } }
<wsdl:definitions name="HostedWCFService" targetNamespace="http://schema.demo.loc/HostWCF" />
Then we remove the one in the WCF Service Contract (corresponds to the wsdl:portType namespace) by adding a namespace to the ServiceContract decoration.
<wsdl:portType name="IHostedWCFService"> <wsdl:operation name="HelloWorld"> <wsdl:input wsaw:Action="http://tempuri.org/IHostedWCFService/HelloWorld" message="tns:IHostedWCFService_HelloWorld_InputMessage" />
using System.ServiceModel; namespace Blog.Examples.HostWCF { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IHostedWCFService" in both code and config file together. [ServiceContract(Namespace = "http://schema.demo.loc/HostWCF")] public interface IHostedWCFService { [OperationContract] string HelloWorld(); } }
<wsdl:input wsaw:Action="http://schema.demo.loc/HostWCF/IHostedWCFService/HelloWorld" />
And finally we control the Action header for the method mapping, by adding our URI to the OperationContract.
using System.ServiceModel; namespace Blog.Examples.HostWCF { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IHostedWCFService" in both code and config file together. [ServiceContract(Namespace = "http://schema.demo.loc/HostWCF")] public interface IHostedWCFService { [OperationContract(Action = "http://schema.demo.loc/HostWCF/HelloWorld")] string HelloWorld(); } }
<wsdl:input wsaw:Action="http://schema.demo.loc/HostWCF/HelloWorld" />
The one http://tempuri.org namespace that remains, is the wsdl:import namespace. This enables the import of the WSDL binding information generated by the Service Factory. Unfortunately, I have not found a way to change these.
<wsdl:import namespace="http://tempuri.org/" location="http://yuriburger.demo.loc/_vti_bin/Blog.Examples.HostWCF/HostedWCFService.svc/mex?wsdl=wsdl0" />
That’s all!
CSKDev: Community Kit for SharePoint: Development Tools Edition
From the CodePlex site:
This project extends the Visual Studio 2010 SharePoint project system with advanced templates and tools. Using these extensions you will be able to find relevant information from your SharePoint environments without leaving Visual Studio. You will have greater productivity while developing SharePoint components and you will have greater deployment capabilities on your local SharePoint installation.
MSDN Article about WCF in SharePoint
http://msdn.microsoft.com/en-us/library/ff521586.aspx
In this excellent article, there is a warning about custom WCF and Claims Based Authentication. Be sure to read this.
Note on MEX
WCF uses a Metadata Exchange endpoint to expose metadata about the service. The CKSDev template takes care of this by adding the [BasicHttpBindingServiceMetadataExchangeEndpoint] to the Service Class.
Image may be NSFW.
Clik here to view.
Clik here to view.
