First write a view model in Webapi
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Implementwebapiinangularjs.Models
{
public class EMPVM
{
[Required(ErrorMessage = "Eid should not be blank.")]
public int? EID { get; set; }
[Required(ErrorMessage = "Name should not be blank.")]
public string NAME { get; set; }
[Required(ErrorMessage = "Address should not be blank.")]
public string ADDRESS { get; set; }
[Required(ErrorMessage = "Password should not be blank.")]
[StringLength(8, MinimumLength = 6, ErrorMessage = "Password length between 6 to 8.")]
public string PASSWORD { get; set; }
[Compare("PASSWORD", ErrorMessage = "Confirm password must be same as password.")]
[Required(ErrorMessage = "Confimr password should not be blank.")]
public string CP { get; set; }
[Required(ErrorMessage = "Please select a gender.")]
public string GENDER { get; set; }
[Required(ErrorMessage = "Please select a hobby.")]
public string HOBBY { get; set; }
[Required(ErrorMessage = "Email should not be blank.")]
[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Invalid email id.")]
public string EMAIL { get; set; }
[Required(ErrorMessage = "Dob should not be blank.")]
[Customvalidation(ErrorMessage="Dob should not greater than or equal to current date.")]
public DateTime? DOB { get; set; }
[Required(ErrorMessage = "SALARY should not be blank.")]
[Range(5000, 500000, ErrorMessage = "Salary range between 5000 to 500000.")]
public decimal? SALARY { get; set; }
[Required(ErrorMessage = "Please select a country.")]
public int? CID { get; set; }
[Required(ErrorMessage = "Please select a state.")]
public int? SID { get; set; }
}
}
public class Customvalidation : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null)
return false;
else
return !(DateTime.Now.Subtract(((DateTime)value)).Days <= 0);
}
}
Web Api
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
[RoutePrefix("api/Empservice")]
public class EmpserviceController : ApiController
{
[HttpGet]
[Route("Allcountry")]
public IHttpActionResult Allcountry()
{
try
{
using (Database1Entities obj = new Database1Entities())
{
return Ok(obj.COUNTRies.ToList());
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpGet]
[Route("Allstate/{CID:int}")]
public IHttpActionResult Allstate(int CID)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
return Ok(obj.STATEs.Where(m=>m.CID==CID).ToList());
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpGet]
[Route("Emps")]
public IHttpActionResult Emps()
{
try
{
using (Database1Entities obj = new Database1Entities())
{
return Ok(obj.EMPs.ToList());
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpGet]
[Route("Emp/{EID:int}",Name="Get")]
public IHttpActionResult Emps(int EID)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
return Ok(obj.EMPs.Find(EID));
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPost]
[Route("Save")]
public IHttpActionResult Save(EMPVM vm)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
if (ModelState.IsValid)
{
EMP emp = new EMP();
emp.EID = vm.EID??0;
emp.NAME = vm.NAME;
emp.ADDRESS = vm.ADDRESS;
emp.PASSWORD = vm.PASSWORD;
emp.GENDER = vm.GENDER;
emp.EMAIL = vm.EMAIL;
emp.SALARY = vm.SALARY;
emp.DOB = vm.DOB;
emp.CID = vm.CID;
emp.SID = vm.SID;
obj.EMPs.Add(emp);
obj.SaveChanges();
return Created(new Uri(Url.Link("Get",new{EID=vm.EID})),"Data Saved");
}
else
return BadRequest(ModelState);
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPut]
[Route("Update/{EID:int}")]
public IHttpActionResult Update([FromUri]int EID,[FromBody]EMPVM vm)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
if (ModelState.IsValid)
{
EMP emp = obj.EMPs.Find(EID);
emp.NAME = vm.NAME;
emp.ADDRESS = vm.ADDRESS;
emp.PASSWORD = vm.PASSWORD;
emp.GENDER = vm.GENDER;
emp.EMAIL = vm.EMAIL;
emp.SALARY = vm.SALARY;
emp.DOB = vm.DOB;
emp.CID = vm.CID;
emp.SID = vm.SID;
obj.SaveChanges();
return Ok("Data Saved");
}
else
return BadRequest(ModelState);
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpDelete]
[Route("Delete/{EID:int}")]
public IHttpActionResult Delete(int EID)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
if (ModelState.IsValid)
{
EMP emp = obj.EMPs.Find(EID);
obj.EMPs.Remove(emp);
obj.SaveChanges();
return Ok("Data Deleted");
}
else
return BadRequest(ModelState);
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Implementwebapiinangularjs.Models
{
public class EMPVM
{
[Required(ErrorMessage = "Eid should not be blank.")]
public int? EID { get; set; }
[Required(ErrorMessage = "Name should not be blank.")]
public string NAME { get; set; }
[Required(ErrorMessage = "Address should not be blank.")]
public string ADDRESS { get; set; }
[Required(ErrorMessage = "Password should not be blank.")]
[StringLength(8, MinimumLength = 6, ErrorMessage = "Password length between 6 to 8.")]
public string PASSWORD { get; set; }
[Compare("PASSWORD", ErrorMessage = "Confirm password must be same as password.")]
[Required(ErrorMessage = "Confimr password should not be blank.")]
public string CP { get; set; }
[Required(ErrorMessage = "Please select a gender.")]
public string GENDER { get; set; }
[Required(ErrorMessage = "Please select a hobby.")]
public string HOBBY { get; set; }
[Required(ErrorMessage = "Email should not be blank.")]
[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Invalid email id.")]
public string EMAIL { get; set; }
[Required(ErrorMessage = "Dob should not be blank.")]
[Customvalidation(ErrorMessage="Dob should not greater than or equal to current date.")]
public DateTime? DOB { get; set; }
[Required(ErrorMessage = "SALARY should not be blank.")]
[Range(5000, 500000, ErrorMessage = "Salary range between 5000 to 500000.")]
public decimal? SALARY { get; set; }
[Required(ErrorMessage = "Please select a country.")]
public int? CID { get; set; }
[Required(ErrorMessage = "Please select a state.")]
public int? SID { get; set; }
}
}
public class Customvalidation : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null)
return false;
else
return !(DateTime.Now.Subtract(((DateTime)value)).Days <= 0);
}
}
Web Api
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
[RoutePrefix("api/Empservice")]
public class EmpserviceController : ApiController
{
[HttpGet]
[Route("Allcountry")]
public IHttpActionResult Allcountry()
{
try
{
using (Database1Entities obj = new Database1Entities())
{
return Ok(obj.COUNTRies.ToList());
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpGet]
[Route("Allstate/{CID:int}")]
public IHttpActionResult Allstate(int CID)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
return Ok(obj.STATEs.Where(m=>m.CID==CID).ToList());
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpGet]
[Route("Emps")]
public IHttpActionResult Emps()
{
try
{
using (Database1Entities obj = new Database1Entities())
{
return Ok(obj.EMPs.ToList());
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpGet]
[Route("Emp/{EID:int}",Name="Get")]
public IHttpActionResult Emps(int EID)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
return Ok(obj.EMPs.Find(EID));
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPost]
[Route("Save")]
public IHttpActionResult Save(EMPVM vm)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
if (ModelState.IsValid)
{
EMP emp = new EMP();
emp.EID = vm.EID??0;
emp.NAME = vm.NAME;
emp.ADDRESS = vm.ADDRESS;
emp.PASSWORD = vm.PASSWORD;
emp.GENDER = vm.GENDER;
emp.EMAIL = vm.EMAIL;
emp.SALARY = vm.SALARY;
emp.DOB = vm.DOB;
emp.CID = vm.CID;
emp.SID = vm.SID;
obj.EMPs.Add(emp);
obj.SaveChanges();
return Created(new Uri(Url.Link("Get",new{EID=vm.EID})),"Data Saved");
}
else
return BadRequest(ModelState);
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPut]
[Route("Update/{EID:int}")]
public IHttpActionResult Update([FromUri]int EID,[FromBody]EMPVM vm)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
if (ModelState.IsValid)
{
EMP emp = obj.EMPs.Find(EID);
emp.NAME = vm.NAME;
emp.ADDRESS = vm.ADDRESS;
emp.PASSWORD = vm.PASSWORD;
emp.GENDER = vm.GENDER;
emp.EMAIL = vm.EMAIL;
emp.SALARY = vm.SALARY;
emp.DOB = vm.DOB;
emp.CID = vm.CID;
emp.SID = vm.SID;
obj.SaveChanges();
return Ok("Data Saved");
}
else
return BadRequest(ModelState);
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpDelete]
[Route("Delete/{EID:int}")]
public IHttpActionResult Delete(int EID)
{
try
{
using (Database1Entities obj = new Database1Entities())
{
if (ModelState.IsValid)
{
EMP emp = obj.EMPs.Find(EID);
obj.EMPs.Remove(emp);
obj.SaveChanges();
return Ok("Data Deleted");
}
else
return BadRequest(ModelState);
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}
}
View in Angular Js
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="angular.js"></script>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
<script src="Scripts/angular-ui/ui-bootstrap.js"></script>
<script src="Scripts/angular-ui/ui-bootstrap-tpls.js"></script>
</head>
<body ng-app="app" ng-controller="Ctrl">
<div class="container" style="padding-top:10px">
<div class="well">
<form class="form-horizontal">
<div class="form-group">
<label class="col-lg-4 control-label">EID</label>
<div class="col-lg-4">
<input type="text" class="form-control" ng-model="EMP.EID" />
<span style="color:red" ng-bind="errEid"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">NAME</label>
<div class="col-lg-4">
<input type="text" class="form-control" ng-model="EMP.NAME" />
<span style="color:red" ng-bind="errName"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">ADDRESS</label>
<div class="col-lg-4">
<textarea class="form-control" ng-model="EMP.ADDRESS" ></textarea>
<span style="color:red" ng-bind="errAdd"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">PASSWORD</label>
<div class="col-lg-4">
<input type="password" class="form-control" ng-model="EMP.PASSWORD" />
<span style="color:red" ng-bind="errPwd"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">CONFIRM PASSWORD</label>
<div class="col-lg-4">
<input type="password" class="form-control" ng-model="EMP.CP" />
<span style="color:red" ng-bind="errCpwd"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">GENDER</label>
<div class="col-lg-4">
<input type="radio" ng-model="EMP.GENDER" value="Male" />Male
<input type="radio" ng-model="EMP.GENDER" value="Female" />Female
<span style="color:red" ng-bind="errSex"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">HOBBY</label>
<div class="col-lg-4">
<select class="form-control" ng-model="EMP.HOBBY" >
<option value="">Select</option>
<option value="Cricket">Cricket</option>
<option value="Football">Football</option>
<option value="Baseball">Baseball</option>
<option value="Hockey">Hockey</option>
</select>
<span style="color:red" ng-bind="errHobby"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">EMAIL</label>
<div class="col-lg-4">
<input type="text" class="form-control" ng-model="EMP.EMAIL" />
<span style="color:red" ng-bind="errEmail"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">DOB</label>
<div class="col-lg-4">
<input type="text" class="form-control" ng-model="EMP.DOB" />
<span style="color:red" ng-bind="errDob"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">SALARY</label>
<div class="col-lg-4">
<input type="text" class="form-control" ng-model="EMP.SALARY" />
<span style="color:red" ng-bind="errSalary"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">COUNTRY</label>
<div class="col-lg-4">
<select class="form-control" ng-model="EMP.CID" ng-options="c.CID as c.CNAME for c in listc" ng-change="fillddl()" >
<option value="">Select</option>
</select>
<span style="color:red" ng-bind="errCid"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label">STATE</label>
<div class="col-lg-4">
<select class="form-control" ng-model="EMP.SID" ng-options="c.SID as c.SNAME for c in lists">
<option value="">Select</option>
</select>
<span style="color:red" ng-bind="errSid"></span>
</div>
</div>
<div class="form-group">
<label class="col-lg-4 control-label"></label>
<div class="col-lg-4">
<input type="button" value="Save" style="width:80px" class="btn btn-primary" ng-click="save()" />
<input type="button" value="Update" style="width:80px" class="btn btn-primary" ng-click="update()" />
<input type="button" value="Reset" style="width:80px" class="btn btn-primary" ng-click="reset()" />
</div>
</div>
</form>
</div>
<div class="well">
<div class="form-group">
<label class="col-lg-1 control-label">SEARCH</label>
<div class="col-lg-3">
<input type="text" placeholder="Search" uib-typeahead="c for c in listName| filter:$viewValue | limitTo:8" ng-model="search.NAME" class="form-control" />
</div>
</div>
<table class="table table-bordered table-condensed table-hover table-responsive table-striped">
<thead class="bg-primary">
<tr>
<th>EID</th>
<th>NAME</th>
<th>GENDER</th>
<th>DOB</th>
<th>SALARY</th>
<th>(RS)SALARY</th>
<th>ACTION</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="c in liste|filter:search">
<td>{{c.EID|Eidfilter}}</td>
<td>{{c.NAME|uppercase}}</td>
<td>{{c.GENDER|lowercase}}</td>
<td>{{c.DOB|date:"dd-MMM-yyyy"}}</td>
<td>{{c.SALARY|number:2}}</td>
<td>{{c.SALARY|currency:'Rs. '}}</td>
<td>
<a ng-click="edit(c.EID)">Edit</a>|
<a ng-click="del(c.EID)">Delete</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
<script type="text/javascript">
angular.module("app", ['ui.bootstrap'])
.controller("Ctrl", function ($scope, factoryEmp) {
function CLR()
{
$scope.EMP = new emp();
$scope.listName = [];
} CLR();
$scope.save = function ()
{
factoryEmp.Save($scope.EMP).error(function (ajXHR) {
if (ajXHR.ModelState["eMPVM.EID"] != "")
$scope.errEid = ajXHR.ModelState["eMPVM.EID"];
else
$scope.errEid = "";
if (ajXHR.ModelState["eMPVM.NAME"] != "")
$scope.errName = ajXHR.ModelState["eMPVM.NAME"];
else
$scope.errName = "";
if (ajXHR.ModelState["eMPVM.ADDRESS"] != "")
$scope.errAdd = ajXHR.ModelState["eMPVM.ADDRESS"];
else
$scope.errAdd = "";
if (ajXHR.ModelState["eMPVM.PASSWORD"] != "")
$scope.errPwd = ajXHR.ModelState["eMPVM.PASSWORD"];
else
$scope.errPwd = "";
if (ajXHR.ModelState["eMPVM.CP"] != "")
$scope.errCpwd = ajXHR.ModelState["eMPVM.CP"];
else
$scope.errCpwd = "";
if (ajXHR.ModelState["eMPVM.GENDER"] != "")
$scope.errSex = ajXHR.ModelState["eMPVM.GENDER"];
else
$scope.errSex = "";
if (ajXHR.ModelState["eMPVM.HOBBY"] != "")
$scope.errHobby = ajXHR.ModelState["eMPVM.HOBBY"];
else
$scope.errHobby = "";
if (ajXHR.ModelState["eMPVM.EMAIL"] != "")
$scope.errEmail = ajXHR.ModelState["eMPVM.EMAIL"];
else
$scope.errEmail = "";
if (ajXHR.ModelState["eMPVM.DOB"] != "")
$scope.errDob = ajXHR.ModelState["eMPVM.DOB"];
else
$scope.errDob = "";
if (ajXHR.ModelState["eMPVM.SALARY"] != "")
$scope.errSalary = ajXHR.ModelState["eMPVM.SALARY"];
else
$scope.errSalary = "";
if (ajXHR.ModelState["eMPVM.CID"] != "")
$scope.errCid = ajXHR.ModelState["eMPVM.CID"];
else
$scope.errCid = "";
if (ajXHR.ModelState["eMPVM.SID"] != "")
$scope.errSid = ajXHR.ModelState["eMPVM.SID"];
else
$scope.errSid = "";
}).then(function (promise) {
alert(promise.data);
CLR();
fill();
});
}
factoryEmp.Getc().then(function (promise) {
$scope.listc = promise.data;
});
function fx(s)
{
factoryEmp.Gets(s).then(function (promise) {
$scope.lists = promise.data;
});
}
$scope.fillddl = function ()
{
fx($scope.EMP.CID);
}
function fill()
{
factoryEmp.Gete().error(function (ajXHR) {
alert(ajXHR.responseText);
}).then(function (promise) {
$scope.liste = promise.data;
for (var i = 0; i < promise.data.length; i++)
{
$scope.listName.push(promise.data[i].NAME);
}
});
} fill();
$scope.edit = function (s)
{
factoryEmp.Get(s).then(function (promise) {
$scope.EMP = promise.data;
fx($scope.EMP.CID);
$scope.EMP.CP = $scope.EMP.PASSWORD;
var dt=new Date($scope.EMP.DOB);
$scope.EMP.DOB = (dt.getMonth() < 10 ? "0" + dt.getMonth() : dt.getMonth()) + "-" + (dt.getDate() < 10 ? "0" + dt.getDate() : dt.getDate()) + "-" + dt.getFullYear();
});
}
$scope.reset = function ()
{
CLR();
}
$scope.update = function () {
factoryEmp.Update($scope.EMP).error(function (ajXHR) {
if (ajXHR.ModelState["eMPVM.EID"] != "")
$scope.errEid = ajXHR.ModelState["eMPVM.EID"];
else
$scope.errEid = "";
if (ajXHR.ModelState["eMPVM.NAME"] != "")
$scope.errName = ajXHR.ModelState["eMPVM.NAME"];
else
$scope.errName = "";
if (ajXHR.ModelState["eMPVM.ADDRESS"] != "")
$scope.errAdd = ajXHR.ModelState["eMPVM.ADDRESS"];
else
$scope.errAdd = "";
if (ajXHR.ModelState["eMPVM.PASSWORD"] != "")
$scope.errPwd = ajXHR.ModelState["eMPVM.PASSWORD"];
else
$scope.errPwd = "";
if (ajXHR.ModelState["eMPVM.CP"] != "")
$scope.errCpwd = ajXHR.ModelState["eMPVM.CP"];
else
$scope.errCpwd = "";
if (ajXHR.ModelState["eMPVM.GENDER"] != "")
$scope.errSex = ajXHR.ModelState["eMPVM.GENDER"];
else
$scope.errSex = "";
if (ajXHR.ModelState["eMPVM.HOBBY"] != "")
$scope.errHobby = ajXHR.ModelState["eMPVM.HOBBY"];
else
$scope.errHobby = "";
if (ajXHR.ModelState["eMPVM.EMAIL"] != "")
$scope.errEmail = ajXHR.ModelState["eMPVM.EMAIL"];
else
$scope.errEmail = "";
if (ajXHR.ModelState["eMPVM.DOB"] != "")
$scope.errDob = ajXHR.ModelState["eMPVM.DOB"];
else
$scope.errDob = "";
if (ajXHR.ModelState["eMPVM.SALARY"] != "")
$scope.errSalary = ajXHR.ModelState["eMPVM.SALARY"];
else
$scope.errSalary = "";
if (ajXHR.ModelState["eMPVM.CID"] != "")
$scope.errCid = ajXHR.ModelState["eMPVM.CID"];
else
$scope.errCid = "";
if (ajXHR.ModelState["eMPVM.SID"] != "")
$scope.errSid = ajXHR.ModelState["eMPVM.SID"];
else
$scope.errSid = ""
}).then(function (promise) {
alert(promise.data);
CLR();
fill();
});
}
$scope.del = function (s)
{
if (confirm('Do you want to delete it?'))
{
factoryEmp.Delete(s).then(function (promise) {
alert(promise.data);
fill();
});
}
}
})
.filter("Eidfilter", function () {
return function (x) {
if (x == 1)
return "Siv1";
else if (x == 2)
return "Sankar1";
else
return "Mahadev1";
}
})
.factory("factoryEmp", function ($http) {
var fac = {};
fac.Getc = function ()
{
return $http.get("http://localhost:5763/api/Empservies/AllCountry");
}
fac.Gets = function (CID) {
return $http.get("http://localhost:5763/api/Empservies/AllState/"+CID);
}
fac.Save = function (EMP) {
return $http.post("http://localhost:5763/api/Empservies/Save",EMP);
}
fac.Gete = function () {
return $http.get("http://localhost:5763/api/Empservies/AllEmps");
}
fac.Get = function (EID) {
return $http.get("http://localhost:5763/api/Empservies/AllEmp/"+EID);
}
fac.Update = function (EMP) {
return $http.put("http://localhost:5763/api/Empservies/Update/"+EMP.EID, EMP);
}
fac.Delete = function (EID)
{
return $http.delete("http://localhost:5763/api/Empservies/Delete/" + EID);
}
return fac;
});
function emp()
{
return {
EID: null,
NAME: null,
ADDRESS: null,
PASSWORD: null,
GENDER: null,
HOBBY: null,
EMAIL: null,
DOB: null,
SALARY: null,
CID: null,
SID:null
}
}
</script>
No comments:
Post a Comment