In this Tutorial I will teach how to Implement your own ASP NET Web API from start. This API will fetch records from the database and provides the consumer with these records in JSON format. This API also implements authentication, meaning users have to provide API Key and Secret for consuming this API.
Add a Web API 2 Controller in your MVC application and name it APIController.
You will also find that the Visual Studio has added a file called WebApiConfig.cs to the App_Start folder. This file contains the routes for this Web API.
To force the API to return data in JSON (and not XML), add the below line at the end of the Register() method on WebApiConfig.cs file.
config.Formatters.Remove(config.Formatters.XmlFormatter);
So the WebApiConfig.cs file will look like this:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
}
You will also have to add the reference of WebApiConfig in Global.asax. For this go to the Application_Start() method of Global.aspx, then add the below line.
System.Web.Http.GlobalConfiguration.Configure(WebApiConfig.Register);
It should look like:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
System.Web.Http.GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
I have a Products table in my Database that has 77 products. This ASP.NET Web API will fetch these products and send them to the client in JSON format.
The Products table look like this:
I am providing you with the script of the products table which you can run in your SQL Server Management Studio.
Download Products Table Script
To fetch the records from database I will use Entity Framework. So create an EDMX file of your database in order to use Entity Framework.
I will create 3 API methods in the Controller so I will be actually creating 3 ASP.NET Web APIs. These are:
Add the below code, to add the GetAllProducts() method, to the controller.
public IEnumerable<Product> GetAllProducts()
{
using (var context = new Entities())
{
var record = context.Products.Select(x => x).ToArray();
return record;
}
}
This method has a return type of IEnumerable, I am fetching all products from Entity Framework Query and filling then on the ‘record’ variable. This variable is returned by this method.
Call GetAllProducts() on the browser
Run your application then navigate to http://localhost:60174/api/API. You will see all the Products in JSON format.
In your controller add another method called GetProduct(). It’s code is given below:
public IHttpActionResult GetProduct(int id)
{
using (var context = new Entities())
{
var totalRecords = context.Products.Count();
var pageSize = 10;
var skip = pageSize * (id - 1);
var canPage = skip < totalRecords;
IEnumerable<Product> record = null;
if (canPage)
{
record = context.Products
.OrderBy(x => x.ProductID)
.Skip(skip)
.Take(pageSize)
.ToArray();
}
var output = new { Total = totalRecords, CurrentPage = id, PageSize = pageSize, Product = record };
return Ok(output);
}
}
To Call the ‘GetProduct()’ method on your browser, navigate to the URL – http://localhost:60174/api/API/2
You will see the JSON returned by it.
Notice that I passed ‘2’ to the URL which is the 2nd page number. The JSON also contains – “Total”:77,”CurrentPage”:2,”PageSize”:10 and so also provides total records, current page and page size.
I will now secure this method so that only those request containing API Key and Secret should get the JSON. The request containing invalid key or secret will get Forbidden Response (403) response.
For creating this feature add a function Authenticate() to the controller:
bool Authenticate()
{
var APICrendential = new[] { new { Key = "Key1", Secret = "Secret1" }, new { Key = "Key2", Secret = "Secret2" }, new { Key = "Key3", Secret = "Secret3" } };
System.Net.Http.Headers.HttpRequestHeaders headers = Request.Headers;
string key = "", secret = "";
if (headers.Contains("Key"))
key = headers.GetValues("Key").First();
if (headers.Contains("Secret"))
secret = headers.GetValues("Secret").First();
int count = (from t in APICrendential where t.Key == key && t.Secret == secret select t).Count();
return count == 0 ? false : true;
}
This method checks the Request Header to find Key & Secret. They are matched with those contained in the variable called APICrendential. If they matches the function returns ‘true’ else it returns value of ‘false’.
Here I am matching the API Key and Secret with 3 values which are:
Note: In real world you will match them against the database.
Now call the Authenticate() function on the first line of the GetProduct() method and return 403 error (Forbidden) for unauthenticated requests.
public IHttpActionResult GetProduct(int id)
{
if (!Authenticate())
return ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden));
using (var context = new Entities())
{
// ...
}
}
Now run the same URL in your browser. This time you will get HTTP ERROR 403 because you haven’t provided the API Key and Secret.
Unlike the above 2 method that were of HTTP GET types, I will create this method as HTTP POST. So this method will only be consumed by requests of type HTTP POST.
[HttpPost]
public IHttpActionResult SearchProduct(string pageNo)
{
if (!Authenticate())
return ResponseMessage(new HttpResponseMessage(HttpStatusCode.Forbidden));
using (var context = new Entities())
{
var record = context.Products.Where(x => x.ProductName == pageNo).ToArray();
var output = new { Product = record };
return Ok(output);
}
}
To make this a POST API, just apply the [HttpPost] attribute to the url.
http://www.demo.yogihosting.com/mvc/api/API
Download link:
Note – you won’t be able to call this method on the browser as this is of HTTP POST type.
I will tell you how to call this method during the consuming procedure. Check the below links for it.
Now it’s time to consume these 3 APIs. I have written 2 tutorials for it.