15 .NET Web API Interview Questions and Answers
Prepare for your interview with this guide on .NET Web API, featuring common questions and detailed answers to enhance your technical skills.
Prepare for your interview with this guide on .NET Web API, featuring common questions and detailed answers to enhance your technical skills.
.NET Web API is a powerful framework for building HTTP services that can be consumed by a wide range of clients, including browsers and mobile devices. Leveraging the robustness of the .NET ecosystem, it allows developers to create scalable and high-performance web services with ease. Its integration with ASP.NET Core further enhances its capabilities, making it a preferred choice for modern web development.
This article provides a curated selection of interview questions designed to test your understanding and proficiency with .NET Web API. By reviewing these questions and their detailed answers, you will be better prepared to demonstrate your technical expertise and problem-solving abilities in your upcoming interviews.
RESTful services are based on principles that enhance web services’ scalability and maintainability. These include:
In .NET Web API, these principles guide the creation of user-friendly and maintainable APIs. Here’s a simple example:
using System.Collections.Generic; using System.Web.Http; public class ProductsController : ApiController { private static List<string> products = new List<string> { "Product1", "Product2", "Product3" }; // GET api/products public IEnumerable<string> Get() { return products; } // GET api/products/5 public string Get(int id) { return products[id]; } // POST api/products public void Post([FromBody] string value) { products.Add(value); } // PUT api/products/5 public void Put(int id, [FromBody] string value) { products[id] = value; } // DELETE api/products/5 public void Delete(int id) { products.RemoveAt(id); } }
HTTP methods, or verbs, perform actions on resources in a Web API. Common methods include:
These methods follow REST architecture principles, creating a predictable API.
Versioning in a Web API can be managed through:
URL Path Versioning is a straightforward approach.
Example:
[ApiVersion("1.0")] [Route("api/v{version:apiVersion}/[controller]")] public class SampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok("This is version 1.0"); } [ApiVersion("2.0")] [Route("api/v{version:apiVersion}/[controller]")] public class SampleV2Controller : ControllerBase { [HttpGet] public IActionResult Get() => Ok("This is version 2.0"); }
Dependency injection (DI) in .NET Web API achieves Inversion of Control (IoC) between classes and their dependencies. It allows for the injection of services into controllers, enhancing modularity and testability.
In .NET Web API, DI is implemented using the built-in IoC container. Services are registered in the Startup
class and injected into controllers via constructor injection.
Example:
// Service Interface public interface IMyService { string GetData(); } // Service Implementation public class MyService : IMyService { public string GetData() { return "Hello from MyService"; } } // Startup.cs public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddTransient<IMyService, MyService>(); // Registering the service } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } // Controller [ApiController] [Route("[controller]")] public class MyController : ControllerBase { private readonly IMyService _myService; public MyController(IMyService myService) { _myService = myService; } [HttpGet] public IActionResult Get() { var data = _myService.GetData(); return Ok(data); } }
Attribute routing in .NET Web API defines routes directly on the controller and action methods using attributes, offering more control and flexibility.
Example:
using System.Web.Http; public class ProductsController : ApiController { [Route("api/products")] [HttpGet] public IHttpActionResult GetAllProducts() { // Code to retrieve all products return Ok(); } [Route("api/products/{id:int}")] [HttpGet] public IHttpActionResult GetProductById(int id) { // Code to retrieve a product by id return Ok(); } [Route("api/products")] [HttpPost] public IHttpActionResult CreateProduct([FromBody] Product product) { // Code to create a new product return Ok(); } }
The Route
attribute defines routes for methods, enhancing readability and maintainability.
Authentication and authorization secure a .NET Web API. Authentication verifies user identity, while authorization determines resource access.
JWT (JSON Web Tokens) are commonly used for authentication due to their stateless nature. Role-based access control (RBAC) manages authorization by assigning roles to users and defining permitted actions.
Example of JWT authentication and RBAC:
// Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "yourIssuer", ValidAudience = "yourAudience", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("yourSecretKey")) }; }); services.AddAuthorization(options => { options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin")); }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } // ExampleController.cs [Authorize] [ApiController] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] [Authorize(Policy = "AdminOnly")] public IActionResult Get() { return Ok("This is an admin-only endpoint."); } }
Middleware in ASP.NET Core is a software component in an application pipeline that handles requests and responses. Each middleware can perform operations before and after the next component is invoked. Middleware components are executed in the order they are added to the pipeline.
Example:
public class RequestLoggingMiddleware { private readonly RequestDelegate _next; public RequestLoggingMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { Console.WriteLine($"Request: {context.Request.Method} {context.Request.Path}"); await _next(context); Console.WriteLine($"Response: {context.Response.StatusCode}"); } } // In Startup.cs public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMiddleware<RequestLoggingMiddleware>(); app.UseMvc(); }
In this example, RequestLoggingMiddleware
logs request and response details.
Logging is essential for tracking application behavior, diagnosing issues, and auditing activities. In .NET, logging is implemented using the built-in logging framework.
To implement logging:
Startup.cs
.ILogger
service into controllers or services.ILogger
methods to log information, warnings, errors, etc.Example:
// Startup.cs public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddLogging(config => { config.AddConsole(); config.AddDebug(); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } // SampleController.cs [ApiController] [Route("[controller]")] public class SampleController : ControllerBase { private readonly ILogger<SampleController> _logger; public SampleController(ILogger<SampleController> logger) { _logger = logger; } [HttpGet] public IActionResult Get() { _logger.LogInformation("Get method called"); return Ok("Hello, world!"); } }
Content negotiation in .NET Web API selects the appropriate response format based on the client’s request, specified via the Accept header. The MediaTypeFormatter class handles this process, with built-in formatters for JSON and XML.
Example:
public class ProductsController : ApiController { public IHttpActionResult Get() { var products = new List<Product> { new Product { Id = 1, Name = "Product1", Price = 10 }, new Product { Id = 2, Name = "Product2", Price = 20 } }; return Ok(products); } }
The framework automatically handles content negotiation based on the client’s Accept header.
Rate limiting in a Web API prevents abuse and ensures fair usage among clients. It helps maintain performance and availability by controlling traffic. In .NET Web API, rate limiting can be implemented using middleware or libraries like AspNetCoreRateLimit.
Example using AspNetCoreRateLimit:
1. Install the AspNetCoreRateLimit package via NuGet.
2. Configure rate limiting settings in appsettings.json.
3. Add services and middleware in Startup.cs.
Example:
// appsettings.json { "IpRateLimiting": { "EnableEndpointRateLimiting": true, "StackBlockedRequests": false, "RealIpHeader": "X-Real-IP", "ClientIdHeader": "X-ClientId", "HttpStatusCode": 429, "GeneralRules": [ { "Endpoint": "*", "Period": "1m", "Limit": 5 } ] } }
// Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddMemoryCache(); services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); services.AddInMemoryRateLimiting(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseIpRateLimiting(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
CORS (Cross-Origin Resource Sharing) is a security feature that prevents web pages from making requests to a different domain than the one that served the web page. In a .NET Web API, CORS can be configured in the Startup.cs
file using middleware.
Example:
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("AllowSpecificOrigin", builder => builder.WithOrigins("http://example.com") .AllowAnyMethod() .AllowAnyHeader()); }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseCors("AllowSpecificOrigin"); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
In this example, a CORS policy named “AllowSpecificOrigin” allows requests from “http://example.com” with any HTTP method and header.
Caching in a Web API improves performance by storing results of expensive operations and reusing them for identical requests. This reduces server load and response times.
In .NET Web API, caching can be implemented using techniques like in-memory caching. Here’s an example using the MemoryCache
class:
using Microsoft.Extensions.Caching.Memory; public class MyController : ControllerBase { private readonly IMemoryCache _cache; public MyController(IMemoryCache cache) { _cache = cache; } [HttpGet("data/{id}")] public IActionResult GetData(int id) { string cacheKey = $"Data_{id}"; if (!_cache.TryGetValue(cacheKey, out string data)) { // Simulate data fetching from a database or external service data = $"Data for ID {id}"; // Set cache options var cacheEntryOptions = new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5), SlidingExpiration = TimeSpan.FromMinutes(2) }; // Save data in cache _cache.Set(cacheKey, data, cacheEntryOptions); } return Ok(data); } }
In this example, MemoryCache
stores and retrieves data, with cache options controlling its lifetime.
Filters in .NET Web API allow custom processing logic at various points in the request pipeline. Types include:
Filters can be applied globally, at the controller level, or at the action level.
Example:
public class CustomActionFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { // Code to execute before the action method is called } public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { // Code to execute after the action method is called } } // Applying the filter at the controller level [CustomActionFilter] public class SampleController : ApiController { public IHttpActionResult Get() { return Ok("Hello, world!"); } }
HATEOAS (Hypermedia as the Engine of Application State) allows clients to interact with a RESTful API through hypermedia provided by the server. This means clients can discover actions and resources through links in responses.
To implement HATEOAS in a .NET Web API, use the Microsoft.AspNetCore.Mvc
library to add hypermedia links to API responses. Create a resource model with data and hypermedia links, then populate these links in controller actions.
Example:
public class ProductResource { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public List<Link> Links { get; set; } = new List<Link>(); } public class Link { public string Href { get; set; } public string Rel { get; set; } public string Method { get; set; } } [ApiController] [Route("api/[controller]")] public class ProductsController : ControllerBase { [HttpGet("{id}")] public IActionResult GetProduct(int id) { var product = new ProductResource { Id = id, Name = "Sample Product", Price = 19.99m }; product.Links.Add(new Link { Href = Url.Link(nameof(GetProduct), new { id = product.Id }), Rel = "self", Method = "GET" }); product.Links.Add(new Link { Href = Url.Link(nameof(UpdateProduct), new { id = product.Id }), Rel = "update", Method = "PUT" }); return Ok(product); } [HttpPut("{id}", Name = nameof(UpdateProduct))] public IActionResult UpdateProduct(int id, [FromBody] ProductResource product) { // Update product logic here return NoContent(); } }
Ensuring the security of sensitive data in a Web API involves several practices: