HI WELCOME TO SIRIS

Understanding Model Binding in ASP.NET Web API

Leave a Comment

 

Before diving in-depth of Model Binding in Web API 2, I would highly recommend you to go ahead and check “Content Negotiation in Web API 2”. The article will give you glimpse over creating Web API projects and how to use POSTMAN for testing your web APIs. For this article, I will consider the same project I created in Content Negotiation and Postman for testing. The mechanism to map the service request and its input data to the correct action method and its parameters is known as Model Binding aka Parameter Binding.

So now, a very genuine question some of you must be thinking “How does the model binder understands, which method to be linked to with the requested URI?” Hmmmm…. A good question!! Let’s see how this is managed.

HOW DOES WEB API BIND THE HTTP VERBS TO THE ACTION METHOD

This is taken care by the WebAPIConfig and HTTP Verbs. The Route config for WebApi tells us the URL parameter it should accept. Observe the RouteTemplate parameter in the below figure. It says that any URL which is decorated with API followed by the controller name, in our case its Products, and also having a facility to provide Id, not mandatory, is a correct URL.

Similarly, when an Action Method is suffixed with HTTP Verb, GET PUT POST DELETE, along with input parameter (non-mandatory) is mapped to the URL

Let us consider the GET method. I requested the URL ‘api/Products’. Ok so now, the model binder first checks if the URL is decorated as required – “Ummm… Yes!! It has an API followed by Controller name. But no ID, ok!! That’s fine. It was anyways optional. I accept the URL. But wait, let me check if there is an input parameter in the request body? No. ok! So there is no input parameter anywhere so this seems to be the GET method. Let me now check in the action method list if I can find any method prefixed with GET and not accepting any input parameter. There it is, the GETPRODUCTS method”. In return, we get back the list of products.

Similarly, it works for other Action methods. But wait, this means I have to always prefix my method name with HTTP Verb? Won’t I be able to ever have a custom name? Let’s see what happens. I changed the GETPRODUCTS to LOADPRODUCTS and called the ‘api/Products’.

We land up getting an error.

So what now? Each HTTP verb is connected to HTTP Method.

HTTP VERB
HTTP METHOD
Get
HttpGet
Post
HttpPost
Put
HttpPut
Delete
HttpDelete

So you simple need to decorate your method with the HTTP Method and rename your method as you desire.

Call the method in Postman and you get the product list back

Similarly, you can decorate your action methods with the desired HTTP Method and get the result.

TYPES OF MODEL BINDER

Model Binders are precisely of two types,

  1. Primitive model binder

  2. Complex model binder

Let’s understand them one-by-one.

Primitive Model Binder

  • If the request is simple, i.e. input parameter are of type int, string, Boolean, GUID, decimal, etc. & is available in the URL, then such kind of request is mapped to primitive model binding.

  • Data is available as Query String

Complex Model Binder

  • If the request is complex, i.e. we pass data in request body as an entity with the desired content-type, then such kind of request is mapped by Complex model binder.

  • Data not available via Query String

DEFAULT MODEL BINDERS

Till now you must have understood what methods use primitive type binding and which methods use complex type binding. I would just note it down though.

Primitive Type Binding

HTTP Methods like GET and DELETE where you are only required to send less quantity of input parameters, uses primitive type binding, by default.

Complex Type Binding

  • HTTP Methods like POST and PUT where you have to send the send model/entity data to the server, uses complex type binding, by default.

  • POST and PUT can also use combination of primitive and complex type. Consider you want to update data. So you can pass the Id in query string and the data to be updated in response body.

But what if I don’t want this default behavior? What if I don’t want to pass my parameter value in query string for GET/Delete methods? What if I want to pass few inputs from query string and few from response body? Can I achieve this? Surely, You can. Let’s see how.

FROMURI AND FROMBODY MODEL BINDER

For explaining the FROMURI and FROMBODY, I will consider the PUT method. As I mentioned above, PUT method accepts Complex type model binding or may be a mix of primitive-complex model binding.

In above image, ‘int id’ is the primitive type which accepts data from the URL or Query String whereas ‘Product product’ is complex type which accepts data from Request Body.

So we can decorate ‘int id’ with [FromUri] and ‘Product product’ as [FromBody]. In both the cases, calling the method and passing parameter would be same, the default behavior. Please Note: For the complex type, you need to pass all the properties mentioned in its entity class in the request body irrespective of ‘int id’ parameter. Now, what if I want to accept the primitive type from the body whereas the complex type from the URI? This can be achieved by decoration our method as follows,

In this case, we need to pass the ‘Id’ parameter through Request Body whereas the ‘Product’ as Query String or Route data.

Let’s see if our action method gets the value when we sent the request.

Ooo yes!! Our action method was successful to receive the input. Similarly, you can choose which input value you want the web API to read from as per your application needs. Also, you can decorate [FromUri] and [FromBody] in other HTTP methods, as per requirement.

SUMMARY

Model Binding is the most powerful mechanism in Web API 2. It enables the response to receive data as per requester choice. i.e. it may be from the URL either form of Query String or Route data OR even from Request Body. It’s just the requester has to decorate the action method with [FromUri] and [FromBody] as desired.

Securing ASP.NET Web API using basic Authentication

Leave a Comment

 In the previous article, I have explained Custom Authentication and Authorization in ASP.NET MVC. Now, I am going to show you how to implement basic HTTP authentication for your Web API by extending ASP.NET WEB API's AuthotrizeAttribute. Before implementing basic HTTP authentication, let's understand what is it?

Basic HTTP Authentication

In basic HTTP authentication, the client passes their username and password in the HTTP request header. Typically, using this technique we encrypt user credentials string into base64 encoded string and decrypt this base64 encoded string into plain text. You can also use another encryption and decryption technique.

Custom Principal

Since WebAPI is build on the top of ASP.NET Framework, hence it can use ASP.NET Framework features like ASP.NET membership and provider. ASP.NET provides IPrincipal and IIdentity interfaces to represents the identity and role for a user. For ASP.NET Web API, you can also create a custom solution by evaluating the IPrincipal and IIdentity interfaces which are bound to the HttpContext as well as the current thread.

public class CustomPrincipal : IPrincipal
 {
 public IIdentity Identity { get; private set; }
 public bool IsInRole(string role)
 {
 if (roles.Any(r => role.Contains(r)))
 {
 return true;
 }
 else
 {
 return false;
 }
 }

 public CustomPrincipal(string Username)
 {
 this.Identity = new GenericIdentity(Username);
 }

 public int UserId { get; set; }
 public string FirstName { get; set; }
 public string LastName { get; set; }
 public string[] roles { get; set; }
 } 

Now you can put this CustomPrincipal objects into the thread’s currentPrinciple property and into the HttpContext’s User property to accomplish your custom authentication and authorization process.

Custom ASP.NET Web API Authorization Filter

Like ASP.NET MVC, Web API also provides Authorization filter to authorize a user. This filter can be applied to an action, a controller, or even globally. This filter is based on AuthorizeAttribute class exist in System.Web.Http namespace. You can customize this filter by overriding OnAuthorization() method as shown below:

//custom authorize filter attribute
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
 private const string BasicAuthResponseHeader = "WWW-Authenticate";
 private const string BasicAuthResponseHeaderValue = "Basic";
 readonly DataContext Context = new DataContext();

 public string UsersConfigKey { get; set; }
 public string RolesConfigKey { get; set; }

 protected CustomPrincipal CurrentUser
 {
 get { return Thread.CurrentPrincipal as CustomPrincipal; }
 set { Thread.CurrentPrincipal = value as CustomPrincipal; }
 }

 public override void OnAuthorization(HttpActionContext actionContext)
 {
 try
 {
 AuthenticationHeaderValue authValue = actionContext.Request.Headers.Authorization;

 if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter) && authValue.Scheme == BasicAuthResponseHeaderValue)
 {
 Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);

 if (parsedCredentials != null)
 {
 var user = Context.Users.Where(u => u.Username == parsedCredentials.Username && u.Password == parsedCredentials.Password).FirstOrDefault();
 if (user != null)
 {
 var roles = user.Roles.Select(m => m.RoleName).ToArray();
 var authorizedUsers = ConfigurationManager.AppSettings[UsersConfigKey];
 var authorizedRoles = ConfigurationManager.AppSettings[RolesConfigKey];

 Users = String.IsNullOrEmpty(Users) ? authorizedUsers : Users;
 Roles = String.IsNullOrEmpty(Roles) ? authorizedRoles : Roles;

 CurrentUser = new CustomPrincipal(parsedCredentials.Username, roles);

 if (!String.IsNullOrEmpty(Roles))
 {
 if (!CurrentUser.IsInRole(Roles))
 {
 actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden);
 actionContext.Response.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue);
 return;
 }
 }

 if (!String.IsNullOrEmpty(Users))
 {
 if (!Users.Contains(CurrentUser.UserId.ToString()))
 {
 actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden);
 actionContext.Response.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue);
 return;
 }
 }

 }
 }
 }
 }
 catch (Exception)
 {
 actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
 actionContext.Response.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue);
 return;

 }
 }

 private Credentials ParseAuthorizationHeader(string authHeader)
 {
 string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(authHeader)).Split(new[] { ':' });

 if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[1]))
 return null;

 return new Credentials() { Username = credentials[0], Password = credentials[1], };
 }
}
//Client credential
public class Credentials
{
 public string Username { get; set; }
 public string Password { get; set; }
}

Applying CustomAuthorize attribute

To make secure your service, decorate your Web API controllers with CustomAuthorize attribute as defined above and specify the uses or roles to access specific service actions/methods. The below product service action Getproduct can be access only by Admin users.

public class ProductController : ApiController
{
 [CustomAuthorize(Roles="Admin")]
 public HttpResponseMessage Getproducts()
 {
 var products = new Product[]
 {
 new Product()
 {
 Id = 1,
 Name = "Soap",
 Price =25.12
 },
 new Product()
 {
 Id = 2,
 Name = "Shampoo",
 Price =25.12
 }
 };

 var response = Request.CreateResponse>(HttpStatusCode.OK, products);
 return response;
 }
}

Calling Web API and passing client credential from ASP.NET MVC

public class HomeController : Controller
{
 //
 // GET: /Home/
 public ActionResult Index()
 {
 string FullName = User.FirstName + " " + User.LastName; 
 
 HttpClient client = new HttpClient();
 
 string authInfo = "admin" + ":" + "123456";
 authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authInfo);

 client.BaseAddress = new Uri("http://localhost:63173/");

 HttpResponseMessage response = client.GetAsync("api/product/").Result;
 if (response.IsSuccessStatusCode)
 {
 // Parse the response body. Blocking!
 var data = response.Content.ReadAsAsync>().Result;
 return View();
 }
 return View();
 }
}
What do you think?

I hope you will enjoy the tips while implementing role-based or user-based security in your ASP.NET Web API. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

How to pass javascript complex object to ASP.NET Web Api and MVC

Leave a Comment

 ASP.NET Web API is one of the most powerful recent addition to the ASP.NET framework. Sometimes, you have to post a form data using jQuery-JSON to Web API or MVC method, which have so many input fields. Passing each and every input field data as a separate parameter is not good practice, even when you have a strongly typed-view. The best practice is, pass a complex type object for all the input fields to the server-side to remove complexity.

In this article, I am going to explain to you how can you pass complex types object to the Web API and MVC method to remove complexity at the server-side and make it simple and useful.

Model Classes

Suppose you have the following Product class and repository for a product.

public class Product
{
 public int Id { get; set; }
 public string Name { get; set; }
 public string Category { get; set; }
 public decimal Price { get; set; }
}

 interface IProductRepository
{
 Product Add(Product item);
 //To Do : Some Stuff
}

public class ProductRepository : IProductRepository
{
 private List<Product> products = new List<Product>();
 private int _nextId = 1;

 public ProductRepository()
 {
 // Add products for the Demonstration
 Add(new Product { Name = "Computer", Category = "Electronics", Price = 23.54M });
 Add(new Product { Name = "Laptop", Category = "Electronics", Price = 33.75M });
 Add(new Product { Name = "iPhone4", Category = "Phone", Price = 16.99M });
 }

 public Product Add(Product item)
 {
 if (item == null)
 {
 throw new ArgumentNullException("item");
 }
 
 // TO DO : Code to save record into database
 item.Id = _nextId++;
 products.Add(item);

 return item;
 }
 //To Do : Some Stuff
}

View (Product.cshtml)

<script type="text/javascript">
//Add New Item by Web API
$("#Save").click(function () {

 //Making complex type object
 var Product = {
 Id: "0",
 Name: $("#Name").val(),
 Price: $("#Price").val(),
 Category: $("#Category").val()
 };
 
 if (Product.Name != "" && Product.Price != "" && Product.Category != "") {
 //Convert javascript object to JSON object
 var DTO = JSON.stringify(Product);
 $.ajax({
 url: 'api/product', //calling Web API controller product
 cache: false,
 type: 'POST',
 contentType: 'application/json; charset=utf-8',
 data: DTO,
 dataType: "json",
 success: function (data) {
 alert('added');
 }
 }).fail(
 function (xhr, textStatus, err) {
 alert(err);
 });

 }
 else {
 alert('Please Enter All the Values !!');
 }

});

</script> 
<div>
 <div>
 <h2>Add New Product</h2>
 </div>
 <div>
 <label for="name">Name</label>
 <input type="text" id="Name" title="Name" />
 </div>

 <div>
 <label for="category">Category</label>
 <input type="text" id="Category" title="Category" />
 </div>

 <div>
 <label for="price">Price</label>
 <input type="text" id="Price" title="Price" />
 </div>
 <br />
 <div>
 <button id="Save">Save</button>
 <button id="Reset">Reset</button>
 </div>
</div>

Web API Controller

public class ProductController : ApiController
{
 static readonly IProductRepository repository = new ProductRepository();
 public Product PostProduct(Product item)
 {
 return repository.Add(item);
 }
} 

How it works?

The same thing you have to done with MVC while calling MVC controller method using jQuery-JSON.

What do you think?

I hope you will enjoy the tips while playing with Asp.Net Web API and MVC. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

Token Based Authentication in ASP.NET Web API

Leave a Comment

 ASP.NET Web API is a service which can be accessed over the HTTP by any client. So, providing security to the Web API is very important, which can be easily done with the process called Token based authentication. Token-based authentication is a process where the user sends his credential to the server, server will validate the user details and generate a token which is sent as response to the users, and user store the token in client side, so client do further HTTP call using this token which can be added to the header and server validates the token and send a response. This article will give you a step by step process to implement the token-based authentication in ASP.NET Web API 2.

Implementation of Token Based Authentication

Step 1

Open visual studio 2017 => create a new Web API project => Name the project, in my case, I named it as Token_Auth_Web_API, set the Authentication to Individual User Account as shown in below figure.

Step 2

Go to Startup.cs file under App_Start folder in the solution

// Configure the application for OAuth based flow
 PublicClientId = "self";
 OAuthOptions = new OAuthAuthorizationServerOptions
 {
 TokenEndpointPath = new PathString("/Token"),
 Provider = new ApplicationOAuthProvider(PublicClientId),
 AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
 AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
 // In production mode set AllowInsecureHttp = false
 AllowInsecureHttp = true
 }; 

Install the Owin using the below command in package manager console

Install-Package Owin -Version 1.0.0

Owin: open web interface for .NET is a middleware which defines the interface between the web server and application.

TokenEndPointPath: This is a kind of request path client applications which communicate with the server directly as part of the OAuth protocol. It must begin with slash “/”

  1. Provider: The object provided by the application to process the event raised by the authorization server middleware.

  2. AuthorizeEndpointPath: The request path where the client application will redirect the client/user to obtain user account to issue a token

  3. AccessTokenExpireTimeSpan : Defines the validity of token

  4. AllowInsecureHttp: It will allow a normal http request to authorize, if it is set to false, it will process only https request.

Step 3

To register the user, we are going to using api/Account/Register Endpoint from a client which is available in AccountController of our WEB API project, as shown below.

 
// POST api/Account/Register
 [AllowAnonymous]
 public async Task<IHttpActionResult> Register(RegisterBindingModel model)
 {
 if (!ModelState.IsValid)
 {
 return BadRequest(ModelState);
 }

 var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };

 IdentityResult result = await UserManager.CreateAsync(user, model.Password);

 if (!result.Succeeded)
 {
 return GetErrorResult(result);
 }

 return Ok();
 }

Go to the Index View of the home controller, as shown in below figure and add the below code

Home=> Index.cshtml
 
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
 <h4> Registration Form</h4>
 <div id="loginDiv" style="width:50%">
 <div style="width:50%">
 <div class="form-group">
 <label for="txtEmail">First Name </label>
 <input type='email' name="email" id="txtEmail" class="form-control">
 </div>
 <div class="form-group">
 <label>Password</label>
 <input type="password" id="textPwd" class="form-control">
 </div>
 <div class="form-group">
 <label>Confrim Password</label>
 <input type="password" id="txtConfirmPwd" class="form-control">
 </div>
 </div>
 <button id="register" class="btn btn-default">Submit</button>
 </div>
 <h4>Login </h4>
 
 <div id="loginDiv" style="width:50%">
 <div class="form-group">
 <label for="txtEmail">First Name </label>
 <input type='email' name="email" id="loginEmail" class="form-control">
 </div>
 <div class="form-group">
 <label>Password</label>
 <input type="password" id="loginPwd" class="form-control">
 </div>
 <button id="btnLogin" class="btn btn-default">Submit</button>
 </div>
 <div>
 <label id="msg"></label>
 </div>
 <script>
 $(document).ready(function () {
 $("#register").on('click', function () {
 var data = { Email: $("#txtEmail").val().trim(), Password: $("#textPwd").val().trim(), ConfirmPassword: $("#txtConfirmPwd").val().trim() };
 $.ajax({
 url: "http://localhost:49501/api/Account/Register",
 type: 'POST',
 data: data,
 success: function (resp) {
 window.location.href = '/Home/Index';
 }
 })
 });
 
 $("#btnLogin").on('click', function () {
 //var data = { Email: $("#loginEmail").val().trim(), Password: $("#textPwd").val().trim(), ConfirmPassword: $("#loginPwd").val().trim() };
 $.ajax(
 {
 url: "/TOKEN",
 type: "POST",
 data: $.param({ grant_type: 'password', username: $("#loginEmail").val(), password: $("#loginPwd").val() }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
 success: function (resp) {
 sessionStorage.setItem('userName', resp.userName);
 sessionStorage.setItem('accessToken', resp.access_token);
 var authHeaders = {};
 authHeaders.Authorization = 'Bearer ' + resp.access_token;
 $.ajax({
 url: "http://localhost:49501/api/values",
 type: "GET",
 headers: authHeaders,
 success: function (response) {
 $("#loginEmail").val("");
 $("#loginPwd").val("");
 $("#msg").text(response);
 }
 });
 
 },
 error: function () {
 $("#msg").text("Authentication failed");
 }
 })
 });
 
 
 })
 </script>
 

From the above HTML code, it is obvious we have two form

  • Registration Form

  • Login Form

Registration Form: Registration Form is used to register the user using the /api/Account/Register API Service which doesn’t require any authentication

Login Form: In this user request to give their credential, once they submit the form /TOKEN post service is fired, once the service validates the user it will generate an access token and send it is as a response to a server with username as shown in below figure.

In Login Ajax call success, we are saving the token and user details, and making another API call /api/values, this function definition is decorated with [Authorize] attribute. we need to pass the access token as an authorization header whenever this HTTP service request happens from the client side.

 // GET api/values
 [EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "X-My-Header")]
 [Authorize]
 public IEnumerable<string> Get()
 {
 return new string[] {"You are successfully Authenticated to Access the Service"};
 }

[EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "X-My-Header")] : Enabled the CROS origin, so that it can be accessed from any domain

[Authorize] : It is used to authenticate the token send from the client side, once the authentication is successfully the Get() will be fired

Client-side HTTP request with Authorization Header

 $("#btnLogin").on('click', function () {
 
 $.ajax(
 {
 url: "/TOKEN",
 type: "POST",
 data: $.param({ grant_type: 'password', username: $("#loginEmail").val(), password: $("#loginPwd").val() }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
 success: function (resp) {
 sessionStorage.setItem('userName', resp.userName);
 sessionStorage.setItem('accessToken', resp.access_token);
 var authHeaders = {};
 authHeaders.Authorization = 'Bearer ' + resp.access_token;
 $.ajax({
 url: "http://localhost:49501/api/values",
 type: "GET",
 headers: authHeaders,
 success: function (response) {
 $("#loginEmail").val("");
 $("#loginPwd").val("");
 $("#msg").text(response);
 }
 });

 },
 error: function () {
 $("#msg").text("Authentication failed");
 }
 })

authHeaders.Authorization = 'Bearer ' + resp.access_token : We are defining the authorization header with the access token when the /api/values HTTP call happens. In server side, the token is validated, once its success it will return a message “You are successfully Authenticated to Access the Service”

Note: we need to send grant_type: 'password' as the data along with user name and password through the body of HTTP request which accessing the URL /TOKEN

Header with /api/values HTTP call

Success

From the above figures, it is obvious the token is validated, and the service returns a message.

Invalid Credential Entry

If the credential is wrong the service /TOKEN will return the error message which is shown above

Read More Articles Related to Web API
Summary

From this article, we have learned the complete process of token-based authentication in ASP.NET Web API 2, where we have seen how to generate the token by sending the user credential and how to use the token with HTTP header for further communication with the server through an HTTP request to access a secured API Service.

Dependency Injection in ASP.NET Web API

Leave a Comment

 Let’s think of a scenario where you are having the fever, you go to a medical shop and ask for medicine but then in return, the medical guy asked which or what type of medicine you need. Ooopz!! Now what? You land up visiting the doctor who understands your needs and writes down the medicine which would work for you. Amazing!! Isn’t it. You got your work done with just a call of service. And that’s what Dependency Injection is in software development.

Dependency Injection aka DI is a way in which one object (The Doctor) is capable to give the dependencies of another object (The patient) as per the need. I won’t be going in depth of explaining Dependency Injection in this article though.

Dependnecy Injection Containers

In the above scenario, different doctors have different ways of treating the illness or giving you the service as per need. Similarly, there are different kinds, popularly known as containers, of dependency injection. In other ways, different design patterns for the dependency injection containers. Below are few of them.

  1. Castle Windsor : This is one of the mature and best Inversion of Control container for .NET and Silverlight applications

  2. Unity : If you are looking for Lightweight extensible dependency injection container, Unity is one of the container you can select from. It comes with support for constructor, property, and method call injection

  3. Autofac : One of the preferred IoC

  4. DryIoc : Simple, fast and fully featured IoC container.

  5. Ninject : Called as ninja of .NET dependency injectors

  6. StructureMap : The original IoC/DI Container for .Net

  7. Spring.Net

  8. Open source application framework

  9. LightInject : An ultra-lightweight IoC container

  10. Simple Injector : An easy-to-use Dependency Injection (DI) library for .NET 4+, It can support Silverlight 4+, Windows Phone 8, Windows 8 including Universal apps and Mono.

  11. Microsoft.Extensions.Dependency Injection : A default IoC container in-built in ASP.NET Core applications.

  12. Scrutor : An extensions for Microsoft.Extensions.Dependency Injection which supports assembly scanning

  13. VS MEF : Managed Extensibility Framework (MEF) implementation used by Visual Studio.

  14. TinyIoC : Best for small scale projects as it’s easy to use and hassle free as well.

    Let us understand the ninja of .Net dependency injection, The Ninject.

Introduction to Ninject in ASP.NET Web API

Ninject is a light-weighted, flexible and open source dependency injector for .Net applications. Due to its flexible nature, managing the application at code level becomes easier and reusable. Ninject is hosted in GitHub. For more details about its advantages and the differences between older-newer versions, you can visit https://github.com/ninject/Ninject

Configuring the Ninject in Web API2

Let’s now see how we can introduce Ninject in our application. I will consider the same example, I created in the article Content Negotiation in ASP.NET WebAPI, I will be enabling the ProductController to use the Ninject Dependecy Injection to exchange the desired data and for testing will be using POSTMAN. If you are unaware of POSTMAN, I would suggest you to first go through Understanding Model Binding in ASP.NET Web API. Here I have explained and how to use POSTMAN. So now let’s get started with the Ninja, The NINJECT!! Current the ProductsController looks as below :

STEP 1

Create an Interface with in the model folder as follows

 
 public interface IProducts
 {
 IQueryable<Product> LoadProducts();
 } 

Please Note, for time being I am only converting the first action method ‘LoadProducts’ to use Ninject. This method brings all the product data from server.

STEP 2

For the body of the method in the interface, I will make database call. To achieve that, first I created a Service Folder under the root project. In that folder, I created a service class ‘ProductService’ which inherits the interface ‘IProducts’. The class looks as follows

 public class ProductService : IProducts
 {
 private AdventureWorksEntities db = new AdventureWorksEntities();
 
 public IQueryable<Product> LoadProducts()
 {
 return db.Products; 
 }
 }
 

STEP 3

Now let us change our ProductsController code to use the interface and the service class.

 private readonly IProducts productRepository;
 
 public ProductsController(IProducts product_Repository)
 {
 this.productRepository = product_Repository;
 }
 
 [HttpGet]
 // GET: api/Products
 public IQueryable<Product> LoadProducts()
 {
 //return db.Products;
 return productRepository.LoadProducts();
 }
 

STEP 4

Now finally the time comes, the time to include The Ninja of Dependency Injection, Ninject in the application. To incorporate Ninject with in the application, firstly we need to install two packages.

  • Ninject.Web.WebApi

  • Ninject.Web.WebApi.WebHost

  • Both the packages are available in Nuget. You can install it either of the way mentioned below,

  • Right click on project => select Manage NuGet packages =>Browse and install the required packages

  • Tools => NuGet Package Manager => Package Manager Console

  • 2.1. If you have multiple projects, you need to select the correct project where you want to install the package.

  • 2.2. PM => Install-Package Ninject.Web.WebApi

  • PM => Install-Package Ninject.Web.WebApi.WebHost

Note that when we install Ninject.Web.WebApi, two more packages get installed automatically

  • Ninject

  • Ninject.Web.Common

Whereas when you install Ninject.Web.Common.WebHost, it installs WebActivatorEx package and also add a new class called Ninject.Web.Common.cs with in App_Start directory.

STEP 5

Now the last step. To enable the use of ProductService class via IProduct interface, we first need to bind them. For this, go to the ‘RegisterServices’ method in ‘Ninject.Web.Common.cs’ file with in App_Start directory.

 
 private static void RegisterServices(IKernel kernel)
 {
 kernel.Bind<IProducts>().To<ProductService>();
 }

Here we are done with making changes in the code to configure Ninject Dependency Injector container. Let’s go ahead and test it using PostMan.

Similarly you can change the code structure for other action methods to use Ninject.

Summary

Dependency Injection being one of the way in which reusability and maintaining the application at code level becomes easy, Ninject serves as a strong open-source IoC for .Net application. Its easily available via NuGet Manager and also under implementing the same is easier.

API Versioning in ASP.NET Core

Leave a Comment

 


Introduction 

 
In this article, we will learn how to version ASP.NET Core Web API and some different ways of versioning the API. We will also create a simple Web API and implement the versioning.
 
Before implementing the versioning, we have to first understand why we need to version API. While working on an existing application or creating a new one, we may create multiple APIs that may be consumed by many clients. When the business has started to grow and expand, new requirements arise. Due to this, we may need to provide more functionality in the existing APIs. However, existing Web API can be consumed by many clients so how to implement the new feature without impacting the existing consumers? We can solve this problem by versioning our API.
 

Create ASP.NET Core Web API 

 
Prerequisites
  1. Visual Studio 16.4 or greater
  2. .NET Core 3.1 installed
  3. Postman for testing Web API(If you don't have already you can download it from here)
Open Visual Studio and click on File -> New -> Project. Select ASP.NET Core Web Application template and click on the Next button
 
API Versioning In ASP.NET Core
 
Give a name to the project and click on the Create button
 
API Versioning In ASP.NET Core
 
Since we have to create an API, select API and click on the Create button.
 
API Versioning In ASP.NET Core
 
That's it. You have created your Web API in ASP.NET Core. 
 
API Versioning In ASP.NET Core
 
In our project, we have one controller create by default named as WeatherForecastController. The next step is to run the application and call the WeatherForecastController API using postman. Hit F5 to run the API which will open a default browser. Open a postman and type the URL "https://localhost:44381/weatherforecast".
 
API Versioning In ASP.NET Core
 
You can see that we have not implemented the versioning yet in the controller. I am going to use this API in the next part of the article where we will see different ways to implement versioning of API.
 

Different ways of Versioning Web API

 
We can do versioning of Web API using the following methods:
  1. Query string
  2. URL 
  3. HTTP header 
There are other ways as well, like accept-header and content type, but in this article, we are going to focus on the above 3 methods.
 
To do versioning in ASP.NET Core Web API, first, we have to install the below the Nuget package which will provide necessary methods for versioning. Right-click on the solution and click on Manage Nuget Package and search for package "Microsoft.AspNetCore.Mvc.Versioning" and install it.
 
API Versioning In ASP.NET Core
 
Once the NuGet package is successfully installed, then the next step is to open Startup.cs and add the below code in the ConfigureServices method.
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.     services.AddControllers();  
  4.     services.AddApiVersioning(x =>  
  5.     {  
  6.         x.DefaultApiVersion = new ApiVersion(1, 0);  
  7.         x.AssumeDefaultVersionWhenUnspecified = true;  
  8.         x.ReportApiVersions = true;  
  9.     });  
  10. }  
Let's understand the above code that we added.
 
Line #6 - DefaultApiVersion is used to set the default version to API
 
Line #7 - This flag AssumeDefaultVersionWhenUnspecified flag is used to set the default version when the client has not specified any versions. If we haven't set this flag to true and client hit the API without mentioning the version then UnsupportedApiVersion exception occurs.
 
Line #8 - To return the API version in response header.
 
So if we hit the same API, we can see the default version in the response header.
 
API Versioning In ASP.NET Core
 
Before discussing about different types, let's create two controllers (i.e EmployeeV1Controller and EmployeeV2Controller) as shown below.
 
EmployeeV1Controller.cs 
  1. using Microsoft.AspNetCore.Mvc;  
  2.   
  3. namespace api_versioning_demo.Controllers  
  4. {  
  5.     [Route("api/employee")]  
  6.     [ApiController]  
  7.     public class EmployeeV1Controller : ControllerBase  
  8.     {  
  9.         [HttpGet]  
  10.         public IActionResult Get()  
  11.         {  
  12.             return new OkObjectResult("employees from v1 controller");  
  13.         }  
  14.     }  
  15. }  
EmployeeV2Controller.cs  
  1. using Microsoft.AspNetCore.Mvc;  
  2.   
  3. namespace api_versioning_demo.Controllers  
  4. {  
  5.     [Route("api/employee")]  
  6.     [ApiController]  
  7.     public class EmployeeV2Controller : ControllerBase  
  8.     {  
  9.         [HttpGet]  
  10.         public IActionResult Get()  
  11.         {  
  12.             return new OkObjectResult("employees from v2 controller");  
  13.         }  
  14.     }  
  15. }  

Query String-Based Versioning

 
In the case of query string based versioning, we have to specify the API version in the query string to call the specific controller. Now we mention the specific version to each controller using [ApiVersion(version_name)] attributes. So our controller looks like the code below: 
  1. using Microsoft.AspNetCore.Mvc;  
  2.   
  3. namespace api_versioning_demo.Controllers  
  4. {  
  5.     [ApiController]  
  6.     [ApiVersion("1.0")]  
  7.     [Route("api/employee")]  
  8.     public class EmployeeV1Controller : ControllerBase  
  9.     {  
  10.         [HttpGet]  
  11.         public IActionResult Get()  
  12.         {  
  13.             return new OkObjectResult("employees from v1 controller");  
  14.         }  
  15.     }  
  16. }  
  1. using Microsoft.AspNetCore.Mvc;  
  2.   
  3. namespace api_versioning_demo.Controllers  
  4. {  
  5.     [ApiController]  
  6.     [ApiVersion("2.0")]  
  7.     [Route("api/employee")]  
  8.     public class EmployeeV2Controller : ControllerBase  
  9.     {  
  10.         [HttpGet]  
  11.         public IActionResult Get()  
  12.         {  
  13.             return new OkObjectResult("employees from v2 controller");  
  14.         }  
  15.     }  
  16. }  
We can call controller using the below routes with the query string method.
 
To call EmployeeV1Controller, we have to hit as https://localhost:44381/api/employee?api-version=1.0
 
API Versioning In ASP.NET Core
 
For EmployeeV2Controller we have to type: https://localhost:44381/api/employee?api-version=2.0
 
API Versioning In ASP.NET Core
 

URL based Versioning

 
In this type of versioning, we can define versions in a URL so that it is more readable. Most users prefer this type over other types. You can to URL based versioning by changing the routs as [Route("api/{v:apiVersion}/Values")].
 
Let's modify the Route attribute in our both controller, as follows.
  1. using Microsoft.AspNetCore.Mvc;  
  2.   
  3. namespace api_versioning_demo.Controllers  
  4. {  
  5.     [ApiController]  
  6.     [ApiVersion("1.0")]  
  7.     [Route("api/{v:apiVersion}/employee")]  
  8.     public class EmployeeV1Controller : ControllerBase  
  9.     {  
  10.         [HttpGet]  
  11.         public IActionResult Get()  
  12.         {  
  13.             return new OkObjectResult("employees from v1 controller");  
  14.         }  
  15.     }  
  16. }  
  1. using Microsoft.AspNetCore.Mvc;  
  2.   
  3. namespace api_versioning_demo.Controllers  
  4. {  
  5.     [ApiController]  
  6.     [ApiVersion("2.0")]  
  7.     [Route("api/{v:apiVersion}/employee")]  
  8.     public class EmployeeV2Controller : ControllerBase  
  9.     {  
  10.         [HttpGet]  
  11.         public IActionResult Get()  
  12.         {  
  13.             return new OkObjectResult("employees from v2 controller");  
  14.         }  
  15.     }  
  16. }  
To call EmployeeV1Controller, we have to hit as https://localhost:44381/api/1.0/employee
 
API Versioning In ASP.NET Core
 
To call EmployeeV2Controller we need: https://localhost:44381/api/2.0/employee
 
API Versioning In ASP.NET Core
 

HTTP Header-Based Versioning

 
In this type, we have to send the version in the Http header when we call the controller. So open the Startup.cs and add the below line of code into services.AddApiVersioning method. Also, delete the version mentioned in routes.
  1. public void ConfigureServices(IServiceCollection services)  
  2.         {  
  3.             services.AddControllers();  
  4.             services.AddApiVersioning(x =>  
  5.             {  
  6.                 x.DefaultApiVersion = new ApiVersion(1, 0);  
  7.                 x.AssumeDefaultVersionWhenUnspecified = true;  
  8.                 x.ReportApiVersions = true;  
  9.                 x.ApiVersionReader = new HeaderApiVersionReader("x-api-version");  
  10.             });  
  11.         }  
Now enable the Http herder versioning type. When a client consumes the API, they have so send x-api-version into the header with specific version value to call the correct controller.
 
API Versioning In ASP.NET Core
 
API Versioning In ASP.NET Core
 

Conclusion

 
In this article, I have explained API Versioning, why we need to versioning, and different types of versioning. Also, I demonstrated an example of each type of versioning. I really hope that you enjoyed this article, share it with friends and please do not hesitate to send me your thoughts or comments.