Monday 26 May 2014

Creating a custom WCF REST service for SharePoint 2013 without a Visual Studio template


  • 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


  1. System.Runtime.Serialization
  2. System.ServiceModel
  3. System.ServiceModel.Web





  • Change the namespace from MyService to your assembly's namespace (e.g., MyRestService) in Service1.svc.cs and IService1.cs



  • Remove a WCF Service Application project to your solution



  • Build your project



  • Using the Visual Studio Command Prompt, go to the project output folder of the SharePoint project


sn -T MyRestService.dll

  • In Service1.svc, change the Service attribute on the ServiceHost directive to be in the following format:
<%@ 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.,

<%@ ServiceHost Language="C#" Debug="true" Service="MyRestService.Service1, MyRestService, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=099213f2a077836f" CodeBehind="Service1.svc.cs" %>


  • Deploy your solution
  • Verify the service loads
  • Note: see below for troubleshooting a common error.
  • Add a HelloWorld operation to your contract, IService1.cs that is set up for REST.
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "HelloWorld")]
string HelloWorld();


  • Implement the operation in Service1.svc.cs
public string HelloWorld()
{
    return "Hello World";

}

  • Update web.config with the appropriate info for your service
 <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceServiceBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true">
          </serviceMetadata>
          <serviceDebug includeExceptionDetailInFaults="true">
          </serviceDebug>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="jsonBehaviour">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="MyRestService.Service1" behaviorConfiguration="MyServiceServiceBehavior">
        <endpoint address="" binding="webHttpBinding" behaviorConfiguration="jsonBehaviour" contract="MyRestService.IService1">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
        </endpoint>
      </service>
    </services>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
    </serviceHostingEnvironment>
  </system.serviceModel>

Test your HelloWorld operation and you should see the following:

http://win-0n4jtsv8137/_vti_bin/Service1.svc/HelloWorld



If you want to use multiple services for same solution you can add Service Details in web config file like below


<services> <service name="LeaveManagementSystem.LMSService" behaviorConfiguration="LMSServiceServiceBehavior"> <endpoint address="" binding="webHttpBinding" behaviorConfiguration="jsonBehaviour" contract="LeaveManagementSystem.LMSIService"> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"> </endpoint> </service> <service name="MyRestService.Service1" behaviorConfiguration="LMSServiceServiceBehavior"> <endpoint address="" binding="webHttpBinding" behaviorConfiguration="jsonBehaviour" contract="MyRestService.IService1"> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"> </endpoint> </service> </services>




  • If you want to pass values through WCF Service

you can write Below code in IService.cs



[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "Types")]

List<Types> Types();


[DataContract]
    public class Types
    {
        [DataMember]
        public int ID { get; set; }

        [DataMember]
        public string Title { get; set; }

    }



you can write Below code in Service.svc.cs



List<Types> IService.Types()
        {
            var resultTypes = new List<Types>();
            DataTable dtType = objLMS.GetType();

            resultLeaveTypes = (from DataRow row in dtType.Rows
                                select new Types
                                {
                                    ID = Convert.ToInt32(row["ID"]),
                                    Title = Convert.ToString(row["Title"])

                                }).ToList();

            return resultTypes;

        }

  • If you want to get values From WCF Service

you can write Below code in IService.cs



[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "ApplyforLeave?Leavetype={Leavetype}&FromDate={FromDate}&ToDate={ToDate}&Duration={Duration}&PhoneNumber={PhoneNumber}&Reason={Reason}")]
void ApplyforLeave(Int32 Leavetype, DateTime FromDate, DateTime ToDate, Int32 Duration, String PhoneNumber, String Reason);


you can write Below code in Service.svc.cs


public void ApplyforLeave(int Leavetype, DateTime FromDate, DateTime ToDate, int Duration, string PhoneNumber, string Reason) {
return "Your value is " + Convert.ToString(Leavetype) + " FromDate is " + Convert.ToString(FromDate) + " ToDate is " + Convert.ToString(ToDate) + " Duration is " + Convert.ToString(Duration) + " PhoneNumber is " + PhoneNumber + " Reason is " + Reason;
}

1 comment:

  1. Hi kittu!

    seems like a good tutorial and thank you for making it. Albeit I have a question:

    How can you secure your service - on https - with a certificate (let us stay at self signed cert) so that one can call it only if the given machine have the cert (on localmachine store perhaps)

    Thanks in advance
    Collapo

    ReplyDelete