Introduction
This tip provides a quick-start on how to create REST based JSON web service using WCF out of the box. REST services are services which enable invoking of method based.
It demonstrates that no explicit serialization to JSON format from a normal .NET object format is required because it can be handled by WCF automatically. It also demonstrates that by writing minimum code and configuration, how can we create JSON output using WCF. This REST service is light-weight, fast, scalable and very easy to update. In majority of web applications, JSON is an inevitable part of programming and page content are usually fed through JSON data by AJAX calls. This service can be used in many scenarios in a .NET environment.
Background
In one of my projects, I need to integrate SharePoint Nintex Forms with data from server side for some validations or pre-populate certain fields. In Nintex Forms, fetching data server side for custom validations is not easy so I developed a REST service using WCF which can be easily called from JavaScript and the data format is in JavaScript Object Notation format. The benefits of this approach are:
- Data usage becomes very easy on client side.
- No extra code required to serialize data to a format easily consumable by JavaScript.
- Very light-weight REST calls which do not hamper performance.
- Easy to maintain as adding or removing key values is as easy as 1,2,3.
Using the Code
This service returns Employee
details like Name
, Department
. To create the service requires the following interfaces and classes:
- IMyRESTService.cs: This is the service contract interface. It also defines the REST URL template and the output type of result.
- MyRESTService.svc.cs:
Service
class implementing IMyRESTService
and defining the function body, which makes a DB call and returns the result. - Employee.cs:
DataContract
class which defines the object definition of Employee
. - SQL.cs: Data access class which queries database, populates result in
employee
object and returns the result to calling method. - EmployeeTable.sql:
Employee
table creation SQL script.
IMyRESTService.cs
using System.ServiceModel;
using System.ServiceModel.Web;
using MyJSONService.Domain;
namespace MyJSONService
{
[ServiceContract]
public interface IMyRESTService
{
[OperationContract]
[WebGet(UriTemplate = "GetEmployee/{employeeNo}", ResponseFormat = WebMessageFormat.Json)]
Employee GetEmployee(string employeeNo);
}
}
MyRESTService.cs
using System;
using MyJSONService.Domain;
using MyJSONService.DataAccess;
using System.ServiceModel;
namespace MyJSONService
{
public class MyRESTService : IMyRESTService
{
public Employee GetEmployee(string employeeNo)
{
try
{
Employee employee = SQL.GetEmployeeDetails(employeeNo);
if (employee == null)
{
throw new FaultException("EMPLOYEE NOT FOUND");
}
return employee;
}
catch (Exception ex)
{
throw new FaultException(ex.Message + ex.StackTrace);
}
}
}
}
Employee.cs
using System.ServiceModel;
using System.Runtime.Serialization;
namespace MyJSONService.Domain
{
[DataContract]
public class Employee
{
[DataMember]
public int EmployeeNo { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string EmployeeEmail { get; set; }
[DataMember]
public string Department { get; set; }
[DataMember]
public string EmployeeManagerName { get; set; }
[DataMember]
public string EmployeeManagerEmail { get; set; }
[DataMember]
public string EmploymentStatus { get; set; }
[DataMember]
public string HomeAddress { get; set; }
}
}
SQL.cs
using System;
using System.Configuration;
using System.Data.SqlClient;
using MyJSONService.Domain;
namespace MyJSONService.DataAccess
{
public class SQL
{
#region Variables
private static string connString = string.Empty;
#endregion
static SQL()
{
connString = ConfigurationManager.AppSettings["DBConnection"];
}
public static Employee GetEmployeeDetails(string employeeNo)
{
Employee employee = null;
string sqlCommand = "select employeeno, employeename,
employeeemail, department, employeemanagername,
employeemanageremail from employee where employeeno=@employeeNo";
using (SqlConnection connection = new SqlConnection(connString))
{
using (SqlCommand command = new SqlCommand(sqlCommand, connection))
{
command.Parameters.AddWithValue("@employeeNo", employeeNo);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
employee = new Employee
{
EmployeeNo = Convert.ToInt32(reader["employeeno"].ToString()),
EmployeeEmail = reader["employeeemail"] as string,
Name = reader["employeename"] as string,
Department = reader["department"] as string,
EmployeeManagerName = reader["employeemanagername"] as string,
EmployeeManagerEmail = reader["employeemanageremail"] as string
};
}
reader.Close();
}
}
return employee;
}
}
}
SQL
USE [Employee]
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Employee](
[EmployeeNo] [int] IDENTITY(1,1) NOT NULL,
[EmployeeName] [nvarchar](100) NULL,
[EmployeeEmail] [nvarchar](200) NULL,
[Department] [nvarchar](100) NULL,
[EmployeeManagerName] [nvarchar](200) NULL,
[EmployeeManagerEmail] [nvarchar](200) NULL
) ON [PRIMARY]
GO
<configuration>
<appsettings>
<add key="DBConnection"
value="Data Source=SQLServerMachineName;Initial Catalog=dbname;user Id=userid;password=pwd">
</add></appsettings>
<system.web>
<compilation debug="true" targetframework="4.0">
<customerrors mode="Off"></customerrors>
</compilation></system.web>
<system.servicemodel>
<behaviors>
<endpointbehaviors>
<behavior name="restfulbehavior">
<webhttp automaticformatselectionenabled="false" defaultbodystyle="WrappedRequest">
</webhttp></behavior>
</endpointbehaviors>
<servicebehaviors>
<behavior>
<servicemetadata httpgetenabled="true">
<servicedebug includeexceptiondetailinfaults="true">
</servicedebug></servicemetadata></behavior>
</servicebehaviors>
</behaviors>
<services>
<service name="MyJSONService.MyRESTService">
<endpoint address="" behaviorconfiguration="restfulbehavior"
binding="webHttpBinding" contract="MyJSONService.IMyRESTService"
name="RESTEndpoint">
</endpoint></service>
</services>
<servicehostingenvironment minfreememorypercentagetoactivateservice="1"
multiplesitebindingsenabled="true">
</servicehostingenvironment></system.servicemodel>
<system.webserver>
<modules runallmanagedmodulesforallrequests="true">
</modules></system.webserver>
</configuration>
Configuration is the most important part of this service. It defines whether the service behaviour configuration is restful. The second important point in the above code is the WebGet
attribute of contract and the URITemplate
that specifies the REST method which is called by the client.
To call the service and use REST method created above, the HTTPGet
URL will be http://testapp/MyRestService.svc/GetEmployee/EmployeeNo, e.g., http://localhost:91/MyRestService.svc/GetEmployee/1.
Points of Interest
The interesting thing to note here is that the output data format can be changed from JSON to XML by just changing the:
[WebGet(UriTemplate = "GetEmployee/{employeeNo}", ResponseFormat = WebMessageFormat.Json)]
to:
[WebGet(UriTemplate = "GetEmployee/{employeeNo}", ResponseFormat = WebMessageFormat.Xml)]
...and the output will be in XML format.
Happy coding!