In today's web development landscape, creating robust APIs and consuming them efficiently is crucial for building modern applications. In this article, we will explore how to build a RESTful API using ASP.NET Web API and consume it using AJAX for seamless interaction between the front-end and back-end.
BackGround
Building upon the foundation laid in our previous article, Simplifying Data Access in ASP.NET MVC WebAPI with Class Library and Entity Framework, where we explored streamlined data access in an ASP.NET MVC WebAPI application using a class library and Entity Framework (without relying on an .edmx file), this article dives deeper. Here, we'll focus on the practical implementation of WebAPI methods that leverage the established data access layer to effectively interact with the retrieved data.
Setting Up the Project
To start, we'll create a solution with two projects:
- DataAccessLayer (Class Library): Contains the Entity Framework DbContext and repository pattern for data access.
- MVC Web API Project: Hosts the API endpoints and serves as the backend.
Step-by-Step Implementation
1. DataAccessLayer Project
In the DataAccessLayer project, we define:
-
DatabaseTransections: Inherits from DbContext
and sets up the database connection. It includes a DbSet
for ProductEntity
and configuration using OnModelCreating
.
-
ProductEntity: Represents a product with properties like ID, ProductName, UnitPrice, and Quantity.
-
ProductRepository: Implements CRUD operations using Entity Framework. Methods like AddProduct
, GetALLProducts
, GetProductByName
, GetProductByID
, and deleteProduct
interact with the database through DatabaseTransections
.
2. MVC Web API Project
Here, we create:
-
ProductController: A controller that exposes API endpoints (GET
, POST
, PUT
, DELETE
) for managing products. Each method in the controller interacts with the ProductRepository
to perform CRUD operations.
-
API Methods:
GetAllProducts
: Retrieves all products. GetProductByName
: Retrieves products matching a given name. AddProduct
: Adds a new product to the database. DeleteProduct
: Deletes a product by its ID.
public class ProductController : ApiController
{
[HttpGet]
public IEnumerable<ProductEntity> GetAllProducts()
{
return new ProductRepository(new DatabaseTransections()).GetALLProducts();
}
[HttpGet]
public HttpResponseMessage GetProductByName(string productName)
{
var entities = new ProductRepository(new DatabaseTransections()).GetProductByName(productName);
if (entities != null)
return Request.CreateResponse(HttpStatusCode.OK, entities);
else
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Product with Name " + productName + " not found");
}
[HttpPost]
public HttpResponseMessage AddProduct([FromBody]ProductEntity _entity)
{
try
{
new ProductRepository(new DatabaseTransections()).AddProduct(_entity);
var message = Request.CreateResponse(HttpStatusCode.Created, _entity);
message.Headers.Location = new Uri(Request.RequestUri + _entity.ID.ToString());
return message;
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
[HttpDelete()]
public HttpResponseMessage DeleteProduct(int id)
{
try
{
var _repository = new ProductRepository(new DatabaseTransections());
var _entity = _repository.GetProductByID(id);
if (_entity != null)
{
_repository.deleteProduct(_entity);
return Request.CreateResponse(HttpStatusCode.OK);
}
else
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "The product with ID " + id + " not found");
}
catch(Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.Conflict, ex);
}
}
}
HTML
This HTML code structures a webpage with two functionalities:
- Load All Products: Clicking the "Load all Products" button triggers an action (likely through JavaScript) to retrieve product data from an API.
- Load Products by Name: Users can enter a product name and click the "Load Products by Name" button. This likely initiates a search function using the entered name to fetch matching products from the API.
The retrieved product data will be displayed in an unordered list (<ul>
) element with the ID ulProducts
.
<div class="row">
<div class="col-md-4">
<div class="col-md-12">
<h2>Load All Products</h2>
<p>Click this button to get all product enlisted in database</p>
<input type="button" id="loadAllProducts" class="btn btn-lg btn-default" value="Load all Products"/>
</div>
<div class="col-md-12">
<h2>Load Product by Name</h2>
<div class="form-group">
<input type="text" id="txtProductName" class="form-control">
<span class="badge rounded-pill"></span>
</div>
<p>Mention name of the product and click on button to load matching products from database</p>
<input type="button" id="loadProductsByName" class="btn btn-lg btn-default" value="Load Products by Name"/>
</div>
</div>
<div class="col-md-8">
<ul id="ulProducts" class="list-group w-50"></ul>
</div>
</div>
Consuming the API Using AJAX
To consume these APIs in a front-end application (like an HTML page):
-
index.html: Contains HTML structure and AJAX scripts to interact with the API endpoints.
-
AJAX Calls: Using jQuery AJAX, we make asynchronous requests to the API endpoints (GET
, POST
, DELETE
).
<script type="text/javascript">
$(document).ready(function () {
var ulProducts = $("#ulProducts");
$("#loadAllProducts").click(function () {
$(ulProducts).empty();
$.ajax({
type: "GET",
url: "http://localhost:53078/api/Product",
datatype: "json",
success: function (data) {
$.each(data, function (index, val) {
ulProducts.append("<li class=\"list-group-item\"><i class=\"glyphicon glyphicon-trash\" onClick = \"deleteProduct(this," + val.ID + ")\"></i> " + val.ProductName + "<span class=\"badge rounded-pill\">" + val.Quantity + "</span></li>");
});
}
});
});
$("#loadProductsByName").click(function () {
var productName = $("#txtProductName").val();
$(ulProducts).empty();
$.ajax({
type: "GET",
url: "http://localhost:53078/api/Product",
datatype: "json",
data: { productName: productName },
success: function (data) {
$.each(data, function (index, val) {
ulProducts.append("<li class=\"list-group-item\"><i class=\"glyphicon glyphicon-trash\" onClick = \"deleteProduct(this," + val.ID + ")\"></i> " + val.ProductName + "<span class=\"badge rounded-pill\">" + val.Quantity + "</span></li>");
});
}
});
});
});
function deleteProduct(listItem, productID) {
debugger;
$.ajax({
type: "DELETE",
url: "http://localhost:53078/api/Product/" + productID,
datatype: "json",
success: function (data, textStatus, xhr) {
if (xhr.status == 200)
$(listItem).parent().remove();
}
});
}
</script>
Conclusion
In this article, we've covered how to build a RESTful API using ASP.NET Web API, implement CRUD operations, and consume the API using AJAX in a front-end application. This setup allows for seamless interaction between the backend and frontend, enabling modern web application development practices.
By following these steps and examples, developers can create powerful APIs and integrate them effectively into their web applications, enhancing both user experience and developer productivity.