WCF Services in SharePoint 2013


Target 
How to host WCF service in SharePoint web environment using Visual Studio.

Constraint
To use WCF service in SharePoint you must review the following constraints :-
a.  WCF Security (RunWithElevatedPrivileges) concern:
        When a web application is configured to use claims authentication (Windows claims, form-based authentication claims, or SAML claims), the Internet Information Services (IIS) website is always configured to have anonymous access turned on. Your custom SOAP and WCF endpoints may receive requests from anonymous users. If you have code in your WCF service that calls the RunWithElevatedPrivileges method to access information without first checking whether the call is from an authorized user or an anonymous user, you risk returning protected SharePoint data to any anonymous user for some of your functions that use that approach.
b.  Using dynamic configuration is preferred in SharePoint.
The recommended way to expose a WCF Service through SharePoint  is to NOT manipulate the Web.Config manually/through code to set your WCF bindings.


Microsoft provide a new methodology called service factory which auto generate appropriate endpoint depending on request of WCF service . it is recommended that you use one of the Service factories provided for you as part of the  Microsoft.SharePoint.Client.Services namespace.

The 3 types of Binding Service Host Factories are as below:
                1. SOAP = MultipleBaseAddressBasicHttpBindingServiceHostFactory (WARNING This has Bugs if                                                the sitecollection is not at the root issue NO.1) read more details end of article.
               
                2. REST = MultipleBaseAddressWebServiceHostFactory

                3. Data Service = MultipleBaseAddressDataServiceHostFactory 

c.  Try to do it your functionality using client object model first.
SharePoint offers the client libraries in different formats to accommodate most developers.
 For web developers who are using scripting languages, the client library is offered in JavaScript.
 For .NET developers, it is offered as a .NET client managed DLL.

what is needed to create WCF service :
1- Add New Project "Empty SharePoint Project"
2- ensure that project  Deploy as a farm solution
3- Add the following references to project   System.Runtime.Serialization , System.ServiceModel and
     Microsoft.SharePoint.Client.ServerRuntime.dll in "c:/Windows/Microsoft.NET/assembly/GAC_MSIL"
4- Add New Item "Interface" as contract of your custom service as following example
[ServiceContract]
Public interface ICalculator
{
        [OperationContract]
        int Sum(int firstNo , int secondNo);
}
 5- Add  New item "class.cs" to specify the implementation of service
[BasicHttpBindingServiceMetadataExchangeEndpointAttribute]
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
Public class Calc : ICalculator
{
        Public int Sum(int firstNo , int secondNo)
       {
             Return firstNo + secondNo;
       }
}
6- Add SharePoint Mapped Folder select "ISAPI"
7- add Text File  to ISAPI mapped folder, name the file *.svc, and then click Add.
8- add the following text to SVC file :
<%@ServiceHost Language="C#" Debug="true" Service="WCFExample.Calculator.BL.Calculator, $SharePoint.Project.AssemblyFullName$" Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressWebServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
9- right-click the project, and then click Unload Project. Right-click the project, click Edit *.csproj and add a <TokenReplacementFileExtensions> tag as follows to the first property group in the .csproj file to enable processing of tokens in .svc file types.
<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>RevertService</RootNamespace>
  <AssemblyName>RevertService</AssemblyName>
  <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
  <FileAlignment>512</FileAlignment>
  <SandboxedSolution>False</SandboxedSolution>
  <TokenReplacementFileExtensions>svc</TokenReplacementFileExtensions>
</PropertyGroup>

WCF configuration Architecture in SharePoint:
At startup, the service factory reads configuration information from IIS and creates appropriate endpoints for every authentication scheme and address that is specified for the available application. However, WCF requires a unique address for every endpoint. If multiple authentication schemes are enabled for a web application, multiple endpoints map to the same address. To resolve this issue, SharePoint Foundation creates a unique address for every authentication scheme. The address is formed by concatenating the base URL of the service with the name of the authentication scheme, such as the following:
http://server/_vti_bin/Service.svc/negotiate
http://server/_vti_bin/Service.svc/ntlm
http://server/_vti_bin/Service.svc/anonymous
When you add a service reference for a custom WCF web service in an application, you do not have to specify the authentication suffix, but can access the web service through its original URL (for example, http://server/_vti_bin/Service.svc). This is possible because of the HTTP Module, a standard element of the SharePoint Foundation infrastructure that preprocesses all requests handled by SharePoint Foundation. The HTTP Module recognizes WCF service configuration convention, and when a request comes to a WCF service that uses dynamic configuration, the module reroutes the request to the appropriate endpoint based on the authentication of the request. This rerouting scheme works transparently for client applications that see only a single WCF service located at the original name that can be accessed through multiple authentication schemes.
How to consume WCF service :
now try to open wcf service from browser. you can write path of .svc file as the following http://servername /_vti_bin/Calculator/Calculator.svc  or go to IIS and open you site you can find your .svc select it and click browse.

 you can consume WCF service using AJAX call as the following :
$.ajax({
type: "GET",
cache: false,
async: false,  
url: "http://servername /_vti_bin/Calculator/Calculator.svc/Calculator",
contentType: "application/json; charset=utf-8",
data: { firstNo : 2, secondNo: 2},
dataType: "json",
success: function (data) {
                                                    if (null != data && typeof (data) != "undefined" && data > 0) {
                                                                alert(data);
                                                     }
                                                                                                               
                                                }
});
issue No.1 details :
the endpoints generated by that factory are only correct if the site is hosted in the root. If your site collection is hosted in say /sites/myportal and you deploy your WCF Service there.then the endpoint will be:
                http://servername/mycompanyname/_vti_bin/myportal/CommonService.svc 
when it should really be
                http://servername/mycompanyname/sites/myportal/_vti_bin/CommonService.svc
so  if you try to query this with the default bindings then the requests will work but they wont have a valid SPContexteven though the HTTP Context is valid.
Workarounds:
1) You can manually change/script the web.config changes to add the correct bindings there.[not recommeded]
2) Use the REST factory as it doesn't suffer from the same issue

10 comments

Nice blog,thanks for sharing this useful information.
Click More Details Visit Our Website

Texus
Texus Systems

Reply

Post a Comment