Representational State Transfer (REST) is a protocol for exchanging data over a distributed environment. The fundamental idea of REST is that we should treat our distributed services as a resource and we should be able to use simple HTTP protocols to do various operations on that resource.
When we talk about the database as a resource we usually talk in terms of Create, Retrieve, Update and Delete (CRUD) operations. Now the philosophy of REST is that for a remote resource all these operations should be possible and they should be possible using simple HTTP protocols.
Now the basic CRUD operations are mapped to the HTTP protocols in the following manner:
- GET: Retrieve the required data (representation of data) from the remote resource.
- POST: Update the current representation of the data on the remote server.
- PUT: Insert new data.
- DELETE: Delete the specified data from the remote server.
Now we will learn this REST WCF service with an example.
Here in this example I will show a REST WCF Service by taking an Employee example.
Now open Visual Studio and select "File" -> "New" -> "Project..." then select WCF in the left side then select WCF Service Application then click "OK".
Image 1.
Now delete the IService.cs and Service.cs files.
Image 2.
Now right-click on the project in the Solution Explorer then select Add New Item then select WCF Service and provide the the name "EmployeeService".
Image 3.
Now I will create a Data Contract as EmployeeDataContract . Right-click on the project in the Solution Explorer then select "Add New Item" then add a .cs file and use the following code:
Image 4.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Runtime.Serialization;
-
- namespace REST_WCF_Service
- {
- [DataContract]
- public class EmployeeDataContract
- {
- [DataMember]
- public string EmployeeID { get; set; }
-
- [DataMember]
- public string Name { get; set; }
-
- [DataMember]
- public string JoiningDate { get; set; }
-
- [DataMember]
- public string CompanyName { get; set; }
-
- [DataMember]
- public string Address { get; set; }
- }
- }
Now open IEmployeeService.cs to define the interface.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.ServiceModel.Web;
- using System.Text;
-
- namespace REST_WCF_Service
- {
-
- [ServiceContract]
- public interface IEmployeeService
- {
-
- [OperationContract]
- [WebGet(UriTemplate = "/GetEmployeeDetails/{EmpId}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
- EmployeeDataContract GetEmployeeDetails(string EmpId);
-
- [OperationContract]
- [WebInvoke(UriTemplate = "/AddNewEmployee", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = "POST")]
- bool AddNewEmployee(EmployeeDataContract emp);
-
- [OperationContract]
- [WebInvoke(Method = "PUT", ResponseFormat = WebMessageFormat.Json)]
- void UpdateEmployee(EmployeeDataContract contact);
-
- [OperationContract]
- [WebInvoke(Method = "DELETE", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "DeleteEmployee/{EmpId}")]
- void DeleteEmployee(string EmpId);
- }
- }
Now open EmployeeService.cs.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.Text;
- using System.Xml.Linq;
-
- namespace REST_WCF_Service
- {
-
-
- public class EmployeeService : IEmployeeService
- {
- public EmployeeDataContract GetEmployeeDetails(string EmpId)
- {
- EmployeeDataContract emp = new EmployeeDataContract();
-
- try
- {
- XDocument doc = XDocument.Load("H:\\EmployeeData.xml");
-
- IEnumerable<XElement> employee =
- (from result in doc.Descendants("DocumentElement").Descendants("Employees")
- where result.Element("EmployeeID").Value == EmpId.ToString()
- select result);
-
- emp.EmployeeID = employee.ElementAt(0).Element("EmployeeID").Value;
- emp.Name = employee.ElementAt(0).Element("Name").Value;
- emp.JoiningDate = employee.ElementAt(0).Element("JoiningDate").Value;
- emp.CompanyName = employee.ElementAt(0).Element("CompanyName").Value;
- emp.Address = employee.ElementAt(0).Element("Address").Value;
- }
- catch (Exception ex)
- {
- throw new FaultException<string>
- (ex.Message);
- }
- return emp;
- }
-
- public bool AddNewEmployee(EmployeeDataContract employee)
- {
- try
- {
- XDocument doc = XDocument.Load("H:\\EmployeeData.xml");
-
- doc.Element("DocumentElement").Add(
- new XElement("Employees",
- new XElement("EmployeeID", employee.EmployeeID),
- new XElement("Name", employee.Name),
- new XElement("JoiningDate", employee.JoiningDate),
- new XElement("CompanyName", employee.CompanyName),
- new XElement("Address", employee.Address)));
-
- doc.Save("H:\\EmployeeData.xml");
- }
- catch (Exception ex)
- {
- throw new FaultException<string>
- (ex.Message);
- }
- return true;
- }
-
- public void UpdateEmployee (EmployeeDataContract employee)
- {
- try
- {
- XDocument doc = XDocument.Load("H:\\EmployeeData.xml");
- var target = doc
- .Element("DocumentElement")
- .Elements("Employees")
- .Where(e => e.Element("EmployeeID").Value == employee.EmployeeID)
- .Single();
-
- target.Element("Name").Value = employee.Name;
- target.Element("JoiningDate").Value = employee.JoiningDate;
- target.Element("CompanyName").Value = employee.CompanyName;
- target.Element("Address").Value = employee.Address;
-
- doc.Save("H:\\EmployeeData.xml");
- }
- catch (Exception ex)
- {
- throw new FaultException<string>
- (ex.Message);
- }
- }
-
- public void DeleteEmployee(string EmpId)
- {
- try
- {
- XDocument doc = XDocument.Load("H:\\EmployeeData.xml");
- foreach (var result in doc.Descendants("DocumentElement").Descendants("Employees"))
- {
- if (result.Element("EmployeeID").Value == EmpId.ToString())
- {
- result.Remove();
- break;
- }
- }
- doc.Save("H:\\EmployeeData.xml");
- }
- catch (Exception ex)
- {
- throw new FaultException<string>
- (ex.Message);
- }
- }
- }
- }
Now create a new project (WindowForm) to consume this REST WCF service. Here I will use a WPF application.
- <Window x:Class="WpfApplication1.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="Consume WCF REST To Perform CRUD Operations" Height="471" Width="625">
- <Grid Margin="0,0,-67,-31">
- <Grid.ColumnDefinitions>
- <ColumnDefinition/>
- <ColumnDefinition Width="37*"/>
- </Grid.ColumnDefinitions>
- <Label Content="Employee Id" HorizontalAlignment="Left" Margin="36,36,0,0" VerticalAlignment="Top" Width="120" Grid.Column="1"/>
- <TextBox HorizontalAlignment="Left" Height="23" Margin="187,36,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.Column="1" Name="txtEmpId"/>
- <Button Content="Click To View Employee Detail" HorizontalAlignment="Left" Margin="329,36,0,0" VerticalAlignment="Top" Width="194" Grid.Column="1" Click="btn_ViewEmployeeDetail"/>
- <Label Content="Employee ID" HorizontalAlignment="Left" Margin="35.632,87,0,0" VerticalAlignment="Top" Grid.Column="1"/>
- <Label Content="Name" HorizontalAlignment="Left" Margin="35.632,135,0,0" VerticalAlignment="Top" Grid.Column="1"/>
- <Label Content="Joining Date" HorizontalAlignment="Left" Margin="35.632,191,0,0" VerticalAlignment="Top" Grid.Column="1"/>
- <Label Content="Company Name" HorizontalAlignment="Left" Margin="35.632,239,0,0" VerticalAlignment="Top" Grid.Column="1"/>
- <Label Content="Address" HorizontalAlignment="Left" Margin="35.632,290,0,0" VerticalAlignment="Top" Grid.Column="1"/>
- <TextBox HorizontalAlignment="Left" Height="23" Margin="187,87,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.Column="1" Name="txtShowEmpId"/>
- <TextBox HorizontalAlignment="Left" Height="23" Margin="187,135,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="187" Grid.Column="1" Name="txtShowEmpName"/>
- <TextBox HorizontalAlignment="Left" Height="23" Margin="187,195,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="187" Grid.Column="1" Name="txtShowEmpJoiningDate"/>
- <TextBox HorizontalAlignment="Left" Height="23" Margin="187,243,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="187" Grid.Column="1" Name="txtShowCompany"/>
- <TextBox HorizontalAlignment="Left" Height="44" Margin="187,290,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="187" Grid.Column="1" Name="txtShowAddress"/>
- <Button Content="Add New Employee" Grid.Column="1" HorizontalAlignment="Left" Margin="50,379,0,0" VerticalAlignment="Top" Width="120" Height="48" Click="btn_AddnewEmployee"/>
- <Button Content="Update Employee" Grid.Column="1" HorizontalAlignment="Left" Margin="205,379,0,0" VerticalAlignment="Top" Width="120" Height="48" Click="btn_UpdateEmployee"/>
- <Button Content="Delete Employee" Grid.Column="1" HorizontalAlignment="Left" Margin="361,379,0,0" VerticalAlignment="Top" Width="120" Height="48" Click="btn_DeleteEmployee"/>
-
- </Grid>
- </Window>
Run the application and do a CRUD operation by consuming REST WCF.
Image 5.
Code to perform the preceding operations is:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- using System.Runtime.Serialization;
- using System.Runtime.Serialization.Json;
- using System.Net;
- using System.IO;
- using REST_WCF_Service;
-
- namespace WPF_ClientApplication
- {
- /// <summary>
- /// Interaction logic for MainWindow.xaml
- /// </summary>
- public partial class MainWindow : Window
- {
- public MainWindow()
- {
- InitializeComponent();
- }
-
- private void btn_AddnewEmployee(object sender, RoutedEventArgs e)
- {
- EmployeeDataContract employee = new EmployeeDataContract
- {
- EmployeeID = txtShowEmpId.Text,
- Name = txtShowEmpName.Text,
- JoiningDate = txtShowEmpJoiningDate.Text,
- CompanyName = txtShowCompany.Text,
- Address = txtShowAddress.Text
- };
-
- DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(EmployeeDataContract));
- MemoryStream mem = new MemoryStream();
- ser.WriteObject(mem, employee);
- string data = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
- WebClient webClient = new WebClient();
- webClient.Headers["Content-type"] = "application/json";
- webClient.Encoding = Encoding.UTF8;
- webClient.UploadString("http://localhost:23610/EmployeeService.svc/AddNewEmployee", "POST", data);
- MessageBox.Show("Employee Saved Successfully...");
-
- txtShowEmpId.Text = "";
- txtShowEmpName.Text = "";
- txtShowEmpJoiningDate.Text = "";
- txtShowCompany.Text = "";
- txtShowAddress.Text = "";
- }
-
- private void btn_ViewEmployeeDetail(object sender, RoutedEventArgs e)
- {
- WebClient proxy = new WebClient();
- string serviceURL = string.Format("http://localhost:23610/EmployeeService.svc/GetEmployeeDetails/{0}", txtEmpId.Text);
- byte[] data = proxy.DownloadData(serviceURL);
- Stream stream = new MemoryStream(data);
- DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(EmployeeDataContract));
- EmployeeDataContract employee = obj.ReadObject(stream) as EmployeeDataContract;
- txtShowEmpId.Text = employee.EmployeeID;
- txtShowEmpName.Text = employee.Name;
- txtShowEmpJoiningDate.Text = employee.JoiningDate;
- txtShowCompany.Text = employee.CompanyName;
- txtShowAddress.Text = employee.Address;
- }
-
- private void btn_UpdateEmployee(object sender, RoutedEventArgs e)
- {
- EmployeeDataContract employeeContact = new EmployeeDataContract
- {
- EmployeeID = txtShowEmpId.Text,
- Name = txtShowEmpName.Text,
- JoiningDate = txtShowEmpJoiningDate.Text,
- CompanyName = txtShowCompany.Text,
- Address = txtShowAddress.Text
- };
-
- WebClient client = new WebClient();
- client.Headers["Content-type"] = "application/json";
-
- MemoryStream ms = new MemoryStream();
- DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(EmployeeDataContract));
- ser.WriteObject(ms, employeeContact);
-
- // invoke the REST method
- client.UploadData("http://localhost:23610/EmployeeService.svc/UpdateEmployee", "PUT", ms.ToArray());
-
- MessageBox.Show("Employee updated Successfully...");
-
- txtShowEmpId.Text = "";
- txtShowEmpName.Text = "";
- txtShowEmpJoiningDate.Text = "";
- txtShowCompany.Text = "";
- txtShowAddress.Text = "";
-
- }
-
- private void btn_DeleteEmployee(object sender, RoutedEventArgs e)
- {
- WebClient client = new WebClient();
- client.Headers["Content-type"] = "application/json";
-
- MemoryStream ms = new MemoryStream();
- DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(string));
- ser.WriteObject(ms, txtEmpId.Text);
-
- // invoke the REST method
- byte[] data = client.UploadData("http://localhost:23610/EmployeeService.svc/DeleteEmployee", "DELETE", ms.ToArray());
-
- MessageBox.Show("Employee deleted Successfully...");
-
- txtShowEmpId.Text = "";
- txtShowEmpName.Text = "";
- txtShowEmpJoiningDate.Text = "";
- txtShowCompany.Text = "";
- txtShowAddress.Text = "";
- }
- }
- }
The following is my XML:
Image 6.