Saturday, 15 March 2014

Creating a custom WCF REST service for SharePoint 2013

Creating a custom WCF REST service for SharePoint 2013



  • Create a new SharePoint 2013 Empty Project as a Farm Solution
  • Add a WCF Service Application project to your solution
  • Add the ISAPI mapped folder to your SharePoint project
  • Drag the Service1.svc and Service1.svc.cs files from the WCF project to the SharePoint project under the ISAPI mapped folder
  • Drag the IService1.cs file from the WCF project to the SharePoint project
  • Add the WCF references to your SharePoint project

    • System.Runtime.Serialization
    • System.ServiceModel
    • System.ServiceModel.Web

  • Change the namespace from WcfService1 to your assembly's namespace (e.g., MyRestService) in Service1.svc.cs and IService1.cs
  • Build your project
  • Using the Visual Studio Command Prompt, go to the project output folder of the SharePoint project
  • Get the PublicKeyToken for your assembly using the strong name utility

    • sn -T MyRestService.dll

  • In Service1.svc, change the Service attribute on the ServiceHost directive to be in the following format:



  • 1
    <%@ ServiceHost Language="C#" Debug="true" Service="{NameSpace}.{ServiceName}, {AssemblyName}, Version=1.0.0.0, Culture=Neutral, PublicKeyToken={PublicKeyToken}" CodeBehind="Service1.svc.cs" %>



      • Replace the tokens here, represented by {Token} with the appropriate values for your project. e.g., 
      1
      <%@ ServiceHost Language="C#" Debug="true" Service="MyRestService.Service1, MyRestService, Version=1.0.0.0, Culture=Neutral, PublicKeyToken={PublicKeyToken}" CodeBehind="Service1.svc.cs" %>
    1. Deploy your solution
    2. Verify the service loads
      • Note: see below for troubleshooting a common error.
    3. Add a HelloWorld operation to your contract, IService1.cs that is set up for REST.
    4. 1
      2
      3
      [OperationContract]
      [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "HelloWorld")
      string HelloWorld();
    5. Implement the operation in Service1.svc.cs




    6. public string HelloWorld()
      {
          return "Hello World";
      }
    7. Update web.config with the appropriate info for your service



















    <behaviors>
        <serviceBehaviors>
            <behavior name="Service1ServiceBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="jsonBehavior">
                <webHttp />
            </behavior    </endpointBehaviors>
    </behaviors>
    <services>
        <service name="MyRestService.Service1" behaviorConfiguration="Service1ServiceBehavior">
            <endpoint address="" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="MyRestService.IService1" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>


    1. Test your HelloWorld operation and you should see the following:


    Troubleshooting

    • If you get an error that says "This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection." this is due to having multiple bindings in IIS, which is common in SharePoint when you have multiple Alternate Access Mappings.
    This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection.



    The property or field 'Title' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.

    The property or field 'Title' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.

    Fix:

     Usually we get this error when we try to use a property before calling ExecuteQuery();
    I find a similar thread here you must call executeQuery and use the property.

    Reference:

    http://social.msdn.microsoft.com/Forums/en-US/f0b4955b-56a2-4af4-b55c-f894b7bf2baa/the-property-or-field-has-not-been-initialized-it-has-not-been-requested-or-the-request-has-not?forum=sharepointdevelopmentlegacy

    http://social.technet.microsoft.com/Forums/sharepoint/en-US/245bae70-0fd7-4d17-9f40-5489db537d65/exception-in-clientcontext-class-while-try-to-get-sharepoint-object?forum=sharepointdevelopmentprevious