CRUD stands for "Create, Read, Update and Delete," which are the four basic database operations. Many HTTP services also model CRUD operations through REST or REST-like APIs.
Introduction
This article explains the walk-through of how to perform "CRUD" operations in a HTTP service using web API
In this context we will see how to add web API controller and perform Crud operations
Before we proceed please have look at
Part 3 of this article series
Adding a web API controller
In Solution Explorer, right-click the the Controllers folder. Select Add and then select Controller.
using BooksStore.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace BooksStore.Controllers
{
public class BooksController : ApiController
{
static readonly IBooksRepository repository = new BooksRepository();
//To get the list of all Books
public IEnumerable<Books> GetAllProducts()
{
return repository.GetAll();
}
//To get a Book by ID
public Books GetProduct(int id)
{
Books item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
//To get books by category:
public IEnumerable<Books> GetProductsByCategory(string category)
{
return repository.GetAll().Where(
p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));
}
public HttpResponseMessage PostProduct(Books item)
{
item = repository.Add(item);
var response = Request.CreateResponse<Books>(HttpStatusCode.Created, item);
string uri = Url.Link("DefaultApi", new { id = item.Id });
response.Headers.Location = new Uri(uri);
return response;
}
//Updating a Book with PUT
public void PutProduct(int id, Books book)
{
book.Id = id;
if (!repository.Update(book))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
//To delete a resource
public void DeleteProduct(int id)
{
repository.Remove(id);
}
}
}
Now lets use the HTML page in Home folder replace with the following code in index.cshtml
@{
ViewBag.Title = "Book Store";
}
@section scripts {
<style type="text/css">
table {
border: 1px solid #000;
border-collapse: collapse;
color: #666666;
min-width: 200px;
}
tr {
border: 1px solid #000;
line-height: 25px;
}
th {
background-color: #B1C3CC;
color: #000;
font-size: 13px;
text-align: left;
}
th, td {
padding-left: 5px;
}
#status {
color: red;
}
</style>
<script src="~/Scripts/knockout-2.1.0.debug.js"></script>
<script src="@Url.Content("~/Scripts/knockout-2.1.0.debug.js")" type="text/javascript"></script>
<script type="text/javascript">
function ViewModel() {
var self = this;
// A nested view model that represents a single book.
function ProductViewModel(book) {
var self = this;
self.Id = book.Id;
self.Author = book.Author;
self.Price = book.Price;
self.Category = book.Category;
}
self.books = ko.observableArray(); // Contains the list of Books
self.book = ko.observable();
self.status = ko.observable();
// Get a list of all products
self.getAll = function () {
self.books.removeAll();
$.getJSON("/api/Books", function (books) {
$.each(books, function (index, book) {
self.books.push(new ProductViewModel(book));
})
});
}
// Find a product by product ID
self.getById = function () {
self.status("");
var id = $('#productId').val();
if (!id.length) {
self.status("ID is required");
return;
}
// Send AJX request to get the product by ID
$.getJSON(
'api/Books/' + id,
function (data) {
self.book(new ProductViewModel(data));
})
// Handler for error response:
.fail(
function (xhr, textStatus, err) {
self.book(null);
self.status(err);
});
}
// Update product details
self.update = function () {
self.status("");
var id = $('#productId').val();
var book = {
Author: $('#name').val(),
Price: $('#price').val(),
Category: $('#category').val()
};
$.ajax({
url: 'api/Books/' + id,
cache: false,
type: 'PUT',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(book),
success: self.getAll
})
.fail(
function (xhr, textStatus, err) {
self.status(err);
});
}
self.create = function () {
self.status("");
var book = {
Author: $('#name2').val(),
Price: $('#price2').val(),
Category: $('#category2').val()
};
$.ajax({
url: 'api/Books',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(book),
statusCode: {
201 /*Created*/: function (data) {
self.books.push(data);
}
}
})
.fail(
function (xhr, textStatus, err) {
self.status(err);
});
}
// Initialize the view-model
$.getJSON("/api/Books", function (books) {
$.each(books, function (index, book) {
self.books.push(new ProductViewModel(book));
})
});
}
function clearStatus() {
$('#status').html('');
}
function add() {
clearStatus();
var book = ko.toJS(viewModel);
var json = JSON.stringify(book);
$.ajax({
url: API_URL,
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: json,
statusCode: {
201 /*Created*/: function (data) {
self.books.push(data);
}
}
});
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
// Initialize jQuery tab widget
$("#tabs").tabs();
</script>
}
<div id="body">
<section class="content-wrapper main-content">
<h3>Books</h3>
<table id="books">
<thead>
<tr><th>ID</th><th>Author</th><th>Category</th><th>Price</th></tr>
</thead>
<tbody data-bind="foreach: books">
<tr>
<td data-bind="text: Id"></td>
<td data-bind="text: Author"></td>
<td data-bind="text: Category"></td>
<td data-bind="text: Price"></td>
</tr>
</tbody>
</table>
</section>
<section id="detail" class="content-wrapper">
<div id="tabs">
<!-- div for jQuery UI tabs -->
<ul>
<li><a href="#viewTab">View Books</a></li>
<li><a href="#addNewTab">Add New Books</a></li>
</ul>
<div id="viewTab">
<label for="productId">ID</label>
<input type="text" title="ID" name='Id' id="productId" size="5" />
<input type="button" value="Get" data-bind="click: getById" />
<div data-bind="if: book()">
<div>
<label for="name">Author</label>
<input data-bind="value: book().Author" type="text" title="Author" id="name" />
</div>
<div>
<label for="category">Category</label>
<input data-bind="value: book().Category" type="text" title="Category" id="category" />
</div>
<div>
<label for="price">Price</label>
<input data-bind="value: book().Price" type="text" title="Price" id="price" />
</div>
<div>
<input type="button" value="Update" data-bind="click: update" />
</div>
</div>
</div>
<div id="addNewTab">
<div>
<label for="name">Author</label>
<input type="text" title="Author" id="name2" />
</div>
<div>
<label for="category">Category</label>
<input type="text" title="Category" id="category2" />
</div>
<div>
<label for="price">Price</label>
<input type="text" title="Price" id="price2" />
</div>
<div>
<input type="button" value="Add New" data-bind="click: create" " />
</div>
</div>
</div>
<div>
<p id="status" data-bind="text: status" />
</div>
</section>
</div>
Lets check the output