WCF Restful CRUD

 

CREATING WCF REST SERVICE PROYECT

 

lets créate a CRUD proyect (backend and front-end using MVC to consume Service).

  • from the SQL Server database you will have to be set a DB and the table with records on there.

CRUD2

and i filled them as follow:

id Name Price Quantity CreationDate
1 Personal 1000 2 2015-01-01
2 Samsung 500 3 2015-01-02
3 Apple 900 6 2015-01-04

  • now lets pass to visual studio:

First of all, let us créate a WCF Service proyect on Visual Studio:

CRUD1

  • First, ad ADO.NET Entity Framework  Model  to have all the entities on our proyect.

crud3

  • Add a new class to créate the entity Product

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace CRUDwithJson

{

public class Product

{

public int id

{

get; set;

}

public string Name

{

get; set;

}

public string Price

{

get; set;

}

public string Quantity

{

get; set;

}

public string CreationDate

{

get; set;

}

}

}

 

  • Now let us créate the Service contract :

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;

namespace CRUDwithJson

{

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IServiceProduct" in both code and config file together.

[ServiceContract]

public interface IServiceProduct

{

[OperationContract]

[WebInvoke(Method = "GET" , UriTemplate ="findall", ResponseFormat = WebMessageFormat.Json)]

List<Product>findAll();

[OperationContract]

[WebInvoke(Method = "GET", UriTemplate = "find/{id}", ResponseFormat = WebMessageFormat.Json)]

Product find(string id);

 

[OperationContract]

[WebInvoke(Method = "POST", UriTemplate = "create", ResponseFormat = WebMessageFormat.Json,

RequestFormat =WebMessageFormat.Json)]

bool create(Product product);

[OperationContract]

[WebInvoke(Method = "PUT", UriTemplate = "edit", ResponseFormat = WebMessageFormat.Json,

RequestFormat = WebMessageFormat.Json)]

bool edit (Product product);

[OperationContract]

[WebInvoke(Method = "DELETE", UriTemplate = "delete", ResponseFormat = WebMessageFormat.Json,

RequestFormat = WebMessageFormat.Json)]

bool delete(Product product);

}

}

 

 

  • and then implement on the  Service class  (.svc )the Service contract as stated down below:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;

namespace CRUDwithJson

{

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "ServiceProduct" in code, svc and config file together.

// NOTE: In order to launch WCF Test Client for testing this service, please select ServiceProduct.svc or ServiceProduct.svc.cs at the Solution Explorer and start debugging.

public class ServiceProduct : IServiceProduct

{

public bool create(Product product)

{

using (MyDemoEntities mde = new MyDemoEntities())

{

try

{

ProductEntity pe = new ProductEntity();

pe.Name = product.Name;

pe.Price = product.Price;

pe.Quantity = product.Quantity;

mde.ProductEntities.Add(pe);

mde.SaveChanges();

return true;

}

catch

{

return false;

}

}

}

public bool delete(Product product)

{

using (MyDemoEntities mde = new MyDemoEntities())

{

try

{

int id = Convert.ToInt32(product.id);

ProductEntity pe = mde.ProductEntities.Single(p => p.id == id);

mde.ProductEntities.Remove(pe);

mde.SaveChanges();

return true;

}

catch

{

return false;

}

}

}

 

public bool edit(Product product)

{

using (MyDemoEntities mde = new MyDemoEntities())

{

try

{

int id = Convert.ToInt32(product.id);

ProductEntity pe = mde.ProductEntities.Single(p => p.id == id);

pe.Name = product.Name;

pe.Price = product.Price;

pe.Quantity = product.Quantity;

mde.SaveChanges();

return true;

}

catch

{

return false;

}

}

}

public Product find(string id)

{

using (MyDemoEntities mde = new MyDemoEntities())

{

int nid = Convert.ToInt32(id);

return mde.ProductEntities.Where(pe => pe.id == nid).Select(pe => new Product

{

id = pe.id,

Name = pe.Name,

Price = pe.Price,

Quantity = pe.Quantity

}).First();

};

}

public List<Product> findAll()

{

using (MyDemoEntities mde = new MyDemoEntities())

{

return mde.ProductEntities.Select(pe => new Product

{

id = pe.id,

Name = pe.Name,

Price = pe.Price,

Quantity = pe.Quantity

}).ToList();

};

}

}

}

 

  •  Now in the webconfig file we may want to type the right binding and set it as httpweb  enabled :

 

 

<?xml version="1.0" encoding="utf-8"?>

<configuration>

<configSections>

<!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 -->

<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

</configSections>

<appSettings>

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

</appSettings>

<system.web>

<compilation debug="true" targetFramework="4.5.2" />

<httpRuntime targetFramework="4.5.2" />

<httpModules>

<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />

</httpModules>

</system.web>

<system.serviceModel>

<services>

<service name="CRUDwithJson.ServiceProduct" behaviorConfiguration="CRUDwithJson_Behavior">

<endpoint address="" binding="webHttpBinding" contract="CRUDwithJson.IServiceProduct"></endpoint>

</service>

</services>

<behaviors>

<endpointBehaviors>

<behavior>

<webHttp/>

</behavior>

</endpointBehaviors>

<serviceBehaviors>

<behavior name="CRUDwithJson_Behavior">

<!-- To avoid disclosing metadata information, set the values below to false before deployment -->

<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />

<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->

<serviceDebug includeExceptionDetailInFaults="false" />

</behavior>

</serviceBehaviors>

</behaviors>

<protocolMapping>

<add binding="basicHttpsBinding" scheme="https" />

</protocolMapping>

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

</system.serviceModel>

<system.webServer>

<modules runAllManagedModulesForAllRequests="true">

<remove name="ApplicationInsightsWebTracking" />

<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />

</modules>

<!--

To browse web app root directory during debugging, set the value below to true.

Set to false before deployment to avoid disclosing web app folder information.

-->

<directoryBrowse enabled="true" />

<validation validateIntegratedModeConfiguration="false" />

</system.webServer>

<connectionStrings>

<add name="MyDemoEntities" connectionString="metadata=res://*/ModelMyDemo.csdl|res://*/ModelMyDemo.ssdl|res://*/ModelMyDemo.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=MININT-2JMB56K\ADK;initial catalog=mydemo;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

</connectionStrings>

<entityFramework>

<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">

<parameters>

<parameter value="mssqllocaldb" />

</parameters>

</defaultConnectionFactory>

<providers>

<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />

</providers>

</entityFramework>

</configuration>

 

if you point to the svc. file on IE    https://localhost:1120/ServiceProduct.svc  you will see how it return Json information needed when Consulting to https://localhost:1120/ServiceProduct.svc/findall

result:

 [{"CreationDate":null,"Name":"Personal","Price":"1000","Quantity":"2","id":1},{"CreationDate":null,"Name":"Samsung","Price":"500","Quantity":"3","id":2},{"CreationDate":null,"Name":"Apple","Price":"900","Quantity":"6","id":3}]

and if you consult only one ítem  https://localhost:1120/ServiceProduct.svc/find/1 
result: 
 {"CreationDate":null,"Name":"Personal","Price":"1000","Quantity":"2","id":1}

 

it Works! lets créate the client now.

 

CONSUMING THE WCF REST SERVICE:

  • Creating an MVC Proyect as a client.

CRUD1

 

  • change the routing config file and place "Product" as stated down below:

 

public class RouteConfig

{

public static void RegisterRoutes(RouteCollection routes)

{

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(

name: "Default",

url: "{controller}/{action}/{id}",

defaults: new { controller = "Product", action = "Index", id = UrlParameter.Optional }

);

}

}

}

 

 

 

 

  • on the model folder we need to créate the  "Product object" to interact with it:

add a class and fill with this information:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.ComponentModel.DataAnnotations;

namespace CRUDWithJSONInWCF_MyRestClient.Models

{

public class Product

{

[Display(Name="id")]

public int id

{

get; set;

}

[Display(Name = "Name")]

public string Name

{

get; set;

}

[Display(Name = "Price")]

public string Price

{

get; set;

}

[Display(Name = "Quantity")]

public string Quantity

{

get; set;

}

[Display(Name = "CreationDate")]

public string CreationDate

{

get; set;

}

}

}

 

 

 

  • Also créate another class as "ProductServiceClient"   class :

 

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Net;

using System.Runtime.Serialization.Json;

using System.Text;

using System.Web;

using System.Web.Script.Serialization;

namespace CRUDWithJSONInWCF_MyRestClient.Models

{

public class ProductServiceClient

{

private string BASE_URL = "https://localhost:1120/ServiceProduct.svc/";

public List<Product> findAll()

{

try

{

var webclient = new WebClient();

var json = webclient.DownloadString(BASE_URL + "findall");

var js = new JavaScriptSerializer();

return js.Deserialize<List<Product>>(json);

}

catch

{

return null;

}

}

public Product find(string id)

{

try

{

var webclient = new WebClient();

string url = string.Format(BASE_URL + "find/{0}", id);

var json = webclient.DownloadString(url);

var js = new JavaScriptSerializer();

return js.Deserialize<Product>(json);

}

catch

{

return null;

}

}

 

public bool create(Product product)

{

try

{

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Product));

MemoryStream mem = new MemoryStream();

ser.WriteObject(mem, product);

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(BASE_URL + "create", "POST", data);

return true;

 

}

catch

{

return false;

}

}

public bool edit (Product product)

{

try

{

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Product));

MemoryStream mem = new MemoryStream();

ser.WriteObject(mem, product);

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(BASE_URL + "edit", "PUT", data);

return true;

 

}

catch

{

return false;

}

}

 

public bool delete(Product product)

{

try

{

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Product));

MemoryStream mem = new MemoryStream();

ser.WriteObject(mem, product);

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(BASE_URL + "delete", "DELETE", data);

return true;

 

}

catch

{

return false;

}

}

 

 

}

}

 

 

  • Now let us créate the controller class :

add a new controller on controller directoty and place this :

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using CRUDWithJSONInWCF_MyRestClient.Models;

using CRUDWithJSONInWCF_MyRestClient.ViewModels;

namespace CRUDWithJSONInWCF_MyRestClient.Controllers

{

public class ProductController : Controller

{

public ActionResult Index()

{

ProductServiceClient psc = new ProductServiceClient();

ViewBag.listProducts = psc.findAll();

return View();

}

[HttpGet]

public ActionResult Create()

{

return View("Create");

}

 

 

[HttpPost]

public ActionResult Create(ProductViewModel pvm)

{

ProductServiceClient psc = new ProductServiceClient();

psc.create(pvm.Product);

return RedirectToAction("Index");

}

 

public ActionResult Delete (string id)

{

ProductServiceClient psc = new ProductServiceClient();

psc.delete(psc.find(id));

return RedirectToAction("Index");

}

[HttpGet]

public ActionResult Edit(string id)

{

ProductServiceClient psc = new ProductServiceClient();

ProductViewModel pvm = new ProductViewModel();

pvm.Product = psc.find(id);

return View("Edit", pvm);

}

 

[HttpPost]

public ActionResult Edit(ProductViewModel pvm)

{

ProductServiceClient psc = new ProductServiceClient();

psc.edit(pvm.Product);

return RedirectToAction("Index");

}

}

}

 

 

  • to interact between view  and model let us créate a folder and call it as ViewModels:

and then add a class  ProductViewModel.cs  filling this as follow:

 

using CRUDWithJSONInWCF_MyRestClient.Models;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace CRUDWithJSONInWCF_MyRestClient.ViewModels

{

public class ProductViewModel

{

public Product Product

{

get;set;

}

}

}

 

 

  • so, now let us créate the view as index.class  in View directory :

 

@{

Layout = null;

}

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width" />

<title>Index</title>

</head>

<body>

<a href="@Url.Action("Create", "Product")">Add a new Product Please</a>

<br /><br /><br />

<table cellpadding="2" cellspacing="2" border="1">

<tr>

<th>Id</th>

<th>Name</th>

<th>Price</th>

<th>Quantity</th>

</tr>

@foreach (var product in ViewBag.listProducts)

{

<tr>

<th>@product.id</th>

<th>@product.Name</th>

<th>@product.Price</th>

<th>@product.Quantity</th>

<th>

<a href="@Url.Action("Delete", "Product", new { id = product.id})">Delete</a>

<a href="@Url.Action("Edit", "Product", new { id = product.id})">Edit</a>

</th>

</tr>

}

</table>

<div>

</div>

</body>

</html>

 

 

if you browse you will be able to see the table with all content from data base.

  • now add the Edit view  and place this :

 

 

@{

Layout = null;

}

@model CRUDWithJSONInWCF_MyRestClient.ViewModels.ProductViewModel

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width" />

<title>Edit</title>

</head>

<body>

@using (Html.BeginForm("Edit", "Product"))

{

<table cellpadding="2" cellspacing="2">

<tr>

<td>@Html.LabelFor(model => model.Product.id)</td>

<td>

@Html.ValueFor(model => model.Product.id)

@Html.HiddenFor(model => model.Product.id)

</td>

</tr>

<tr>

<td>@Html.LabelFor(model=>model.Product.Name)</td>

<td>@Html.TextBoxFor(model => model.Product.Name)</td>

</tr>

<tr>

<td>@Html.LabelFor(model => model.Product.Price)</td>

<td>@Html.TextBoxFor(model => model.Product.Price)</td>

</tr>

<tr>

<td>@Html.LabelFor(model => model.Product.Quantity)</td>

<td>@Html.TextBoxFor(model => model.Product.Quantity)</td>

</tr>

<tr>

<td>&nbsp;</td>

<td><input type="submit" value="Save"/></td>

</tr>

</table>

}

 

<div>

</div>

</body>

</html>

 

  • and last but no lest  add the créate  view :

 

@{

Layout = null;

}

@model CRUDWithJSONInWCF_MyRestClient.ViewModels.ProductViewModel

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width" />

<title>Create</title>

</head>

<body>

@using (Html.BeginForm("Create", "Product"))

{

<table cellpadding="2" cellspacing="2">

<tr>

<td>@Html.LabelFor(model=>model.Product.Name)</td>

<td>@Html.TextBoxFor(model => model.Product.Name)</td>

</tr>

<tr>

<td>@Html.LabelFor(model => model.Product.Price)</td>

<td>@Html.TextBoxFor(model => model.Product.Price)</td>

</tr>

<tr>

<td>@Html.LabelFor(model => model.Product.Quantity)</td>

<td>@Html.TextBoxFor(model => model.Product.Quantity)</td>

</tr>

<tr>

<td>&nbsp;</td>

<td><input type="submit" value="Save"/></td>

</tr>

</table>

}

 

<div>

</div>

</body>

</html>

 

Now if you browse you will be able to CRUD :

crud4

 

hope this can be usefull to you. thanks :)