Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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.
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:
- First, ad ADO.NET Entity Framework Model to have all the entities on our proyect.
- 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="data source=MININT-2JMB56K\ADK;initial catalog=mydemo;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" 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.
- 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> </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> </td>
<td><input type="submit" value="Save"/></td>
</tr>
</table>
}
<div>
</div>
</body>
</html>
Now if you browse you will be able to CRUD :
hope this can be usefull to you. thanks :)
Comments
- Anonymous
August 08, 2016
:) - Anonymous
September 07, 2016
exellent! thank you - Anonymous
May 05, 2017
wao, exellent! amigo