Interview

15 Web API C# Interview Questions and Answers

Prepare for your next interview with our comprehensive guide on Web API development using C#. Enhance your skills and boost your confidence.

Web API development using C# is a critical skill in modern software engineering. C# is a versatile and powerful language that, when combined with the .NET framework, allows developers to create robust and scalable web APIs. These APIs are essential for enabling communication between different software systems, facilitating data exchange, and supporting a wide range of applications from web services to mobile apps.

This article offers a curated selection of interview questions designed to test and enhance your knowledge of Web API development in C#. By working through these questions, you will gain a deeper understanding of key concepts, best practices, and common challenges, thereby improving your readiness for technical interviews and your overall proficiency in the field.

Web API C# Interview Questions and Answers

1. Explain the role of HTTP verbs in Web API and how they map to CRUD operations.

HTTP verbs in Web APIs specify the type of operation to be performed on a resource. They map to CRUD operations as follows:

  • GET: Retrieves data from the server, mapping to “Read” in CRUD.
  • POST: Sends data to create a new resource, mapping to “Create” in CRUD.
  • PUT: Updates an existing resource, mapping to “Update” in CRUD.
  • DELETE: Removes a resource, mapping to “Delete” in CRUD.
  • PATCH: Applies partial modifications to a resource, also part of “Update” in CRUD.

2. Write a method to create a simple GET endpoint that returns a list of strings.

To create a simple GET endpoint in a Web API using C#, define a controller with a method that handles the GET request and returns a list of strings:

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace WebApiExample.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            var values = new List<string> { "value1", "value2", "value3" };
            return Ok(values);
        }
    }
}

The ValuesController class specifies the base URL for the controller. The Get method, decorated with [HttpGet], returns a list of strings wrapped in an ActionResult.

3. How would you secure a Web API endpoint?

Securing a Web API endpoint involves:

  • Authentication: Verifying the identity of the user or system accessing the API, using methods like JWT, OAuth, or API keys.
  • Authorization: Ensuring the authenticated user has the necessary permissions, managed through role-based or claims-based authorization.
  • Data Protection: Securing data transmission with HTTPS and implementing data validation to prevent attacks.

Example of implementing JWT authentication:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = Configuration["Jwt:Issuer"],
                ValidAudience = Configuration["Jwt:Audience"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
            };
        });

    services.AddAuthorization(options =>
    {
        options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
    });

    services.AddControllers();
}

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = "AdminOnly")]
[HttpGet("secure-endpoint")]
public IActionResult SecureEndpoint()
{
    return Ok("This is a secure endpoint.");
}

4. Write a method to create a POST endpoint that accepts a JSON object and returns a status message.

To create a POST endpoint in a Web API using C#, define a controller with an action method that handles HTTP POST requests. The method should accept a JSON object, represented by a model class, process the input, and return a status message.

Example:

using Microsoft.AspNetCore.Mvc;

namespace WebApiExample.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ExampleController : ControllerBase
    {
        public class InputModel
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        [HttpPost]
        public IActionResult Post([FromBody] InputModel input)
        {
            if (input == null)
            {
                return BadRequest("Invalid input");
            }

            // Process the input as needed
            return Ok("Data received successfully");
        }
    }
}

5. What is dependency injection and how is it implemented in Web API?

Dependency injection (DI) in Web API is a technique to achieve Inversion of Control (IoC) between classes and their dependencies. It allows the creation of dependent objects outside of a class and provides those objects to a class in various ways, making the code more modular and testable.

In a Web API project, DI is typically implemented using a built-in IoC container. The services and their dependencies are registered in the Startup.cs file, and the framework takes care of injecting these dependencies where needed.

Example:

// Define an interface
public interface IMyService
{
    string GetData();
}

// Implement the interface
public class MyService : IMyService
{
    public string GetData()
    {
        return "Hello, Dependency Injection!";
    }
}

// Register the service in Startup.cs
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddTransient<IMyService, MyService>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

// Consume the service in a 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);
    }
}

6. Explain the role of Media Type Formatters in Web API and how they work.

Media Type Formatters in Web API serialize request/response data to and from different formats, supporting multiple content types. They inspect the Content-Type and Accept headers to determine the appropriate format for the request and response.

Example:

public static void Register(HttpConfiguration config)
{
    // Remove the XML formatter
    config.Formatters.Remove(config.Formatters.XmlFormatter);

    // Add a custom JSON formatter
    config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;

    // Add a custom media type formatter
    config.Formatters.Add(new CustomMediaTypeFormatter());
}

public class CustomMediaTypeFormatter : MediaTypeFormatter
{
    public CustomMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/custom"));
    }

    public override bool CanReadType(Type type)
    {
        return type == typeof(MyCustomType);
    }

    public override bool CanWriteType(Type type)
    {
        return type == typeof(MyCustomType);
    }

    public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
    {
        // Custom deserialization logic
    }

    public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        // Custom serialization logic
    }
}

7. How do you implement versioning in Web API?

Versioning in Web API maintains backward compatibility while evolving the API. Strategies include:

  • URL Path Versioning: Including the version number in the URL path.
  • Query String Versioning: Specifying the version number as a query parameter.
  • Header Versioning: Including the version number in the request header.
  • Accept Header Versioning: Specifying the version in the Accept header using media types.

Example of URL path versioning:

[Route("api/v1/products")]
public class ProductsV1Controller : ApiController
{
    public IHttpActionResult Get()
    {
        return Ok("This is version 1");
    }
}

[Route("api/v2/products")]
public class ProductsV2Controller : ApiController
{
    public IHttpActionResult Get()
    {
        return Ok("This is version 2");
    }
}

Two versions of the Products controller are created, each with a different route, allowing clients to specify which version to use.

8. Write a method to create a PUT endpoint that updates an existing resource.

In a C# Web API, a PUT endpoint updates an existing resource. The PUT method is idempotent, meaning multiple identical requests have the same effect as a single request. Define a method in your controller that accepts the updated resource data and updates the corresponding resource in the database.

Example:

[HttpPut("{id}")]
public IActionResult UpdateResource(int id, [FromBody] ResourceModel updatedResource)
{
    if (id != updatedResource.Id)
    {
        return BadRequest();
    }

    var resource = _context.Resources.Find(id);
    if (resource == null)
    {
        return NotFound();
    }

    resource.Name = updatedResource.Name;
    resource.Value = updatedResource.Value;

    _context.Entry(resource).State = EntityState.Modified;
    _context.SaveChanges();

    return NoContent();
}

The UpdateResource method checks if the id matches the Id of the updatedResource. If not, it returns a BadRequest response. It then attempts to find the existing resource in the database. If the resource is not found, it returns a NotFound response. If the resource is found, it updates the resource’s properties and saves the changes to the database. Finally, it returns a NoContent response to indicate that the update was successful.

9. Explain how middleware works in ASP.NET Core and how it can be used in Web API.

Middleware in ASP.NET Core is a series of components executed in a specific order to handle HTTP requests and responses. Each component can perform operations before and after the next component in the pipeline is invoked, allowing for a modular approach to handling cross-cutting concerns.

Example of custom middleware:

public class CustomMiddleware
{
    private readonly RequestDelegate _next;

    public CustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // Pre-processing logic
        Console.WriteLine("Handling request: " + context.Request.Path);

        await _next(context);

        // Post-processing logic
        Console.WriteLine("Finished handling request.");
    }
}

// In Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMiddleware<CustomMiddleware>();

    app.UseMvc();
}

The CustomMiddleware class logs the request path before passing the request to the next middleware component and logs a message after the request has been handled.

10. Write a method to create a DELETE endpoint that removes a resource by ID.

To create a DELETE endpoint in a Web API using C#, define a method in a controller that handles HTTP DELETE requests. This method should accept an ID parameter, locate the resource by that ID, and then remove it from the data store.

Example:

[Route("api/[controller]")]
[ApiController]
public class ResourcesController : ControllerBase
{
    private readonly DataContext _context;

    public ResourcesController(DataContext context)
    {
        _context = context;
    }

    // DELETE: api/Resources/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteResource(int id)
    {
        var resource = await _context.Resources.FindAsync(id);
        if (resource == null)
        {
            return NotFound();
        }

        _context.Resources.Remove(resource);
        await _context.SaveChangesAsync();

        return NoContent();
    }
}

The DeleteResource method uses the [HttpDelete("{id}")] attribute to specify that it handles DELETE requests for a resource identified by an ID. It first attempts to find the resource by its ID. If the resource is not found, it returns a NotFound response. If the resource is found, it is removed from the data store, and the changes are saved. Finally, a NoContent response is returned to indicate that the deletion was successful.

11. Explain the concept of content negotiation in Web API.

Content negotiation in Web API is the process by which the server selects the best representation for a given response when there are multiple representations available. This is typically based on the Accept header in the HTTP request, which specifies the media types that the client can handle. The server then uses this information to return the data in the requested format.

In C#, content negotiation is handled by the framework, which inspects the Accept header and selects the appropriate formatter to serialize the response. The default formatters in ASP.NET Web API include JSON and XML formatters, but custom formatters can also be added.

Example:

public class ProductsController : ApiController
{
    public IHttpActionResult GetProduct(int id)
    {
        var product = new Product { Id = id, Name = "Sample Product" };
        return Ok(product); // The framework will handle content negotiation
    }
}

In this example, the GetProduct method returns an IHttpActionResult. The framework will automatically handle content negotiation based on the Accept header in the request. If the client requests JSON, the response will be serialized as JSON. If the client requests XML, the response will be serialized as XML.

12. How do you implement caching in Web API?

Caching in a Web API can be implemented using various strategies such as in-memory caching, distributed caching, and response caching. In-memory caching stores data in the memory of the web server, making it fast but limited by the server’s memory capacity. Distributed caching, on the other hand, stores data in a distributed cache like Redis or Memcached, which can be shared across multiple servers. Response caching stores the HTTP response and serves it directly for subsequent requests.

Here is a simple example of in-memory caching using the IMemoryCache interface in ASP.NET Core:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using System;

namespace WebApiCachingExample.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class DataController : ControllerBase
    {
        private readonly IMemoryCache _cache;
        private readonly string cacheKey = "cachedData";

        public DataController(IMemoryCache cache)
        {
            _cache = cache;
        }

        [HttpGet]
        public IActionResult GetData()
        {
            if (!_cache.TryGetValue(cacheKey, out string cachedData))
            {
                // Simulate data fetching
                cachedData = "This is the data to be cached.";
                var cacheEntryOptions = new MemoryCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
                    SlidingExpiration = TimeSpan.FromMinutes(2)
                };

                _cache.Set(cacheKey, cachedData, cacheEntryOptions);
            }

            return Ok(cachedData);
        }
    }
}

In this example, the GetData method checks if the data is already cached. If not, it fetches the data, stores it in the cache with specific expiration policies, and then returns the cached data.

13. Write a method to create a custom action filter in Web API.

Action filters in Web API allow you to execute custom logic before or after an action method runs. They are useful for cross-cutting concerns such as logging, authentication, and validation. To create a custom action filter in Web API, you need to implement the IActionFilter interface or derive from the ActionFilterAttribute class.

Example:

using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Diagnostics;

public class CustomActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        // Custom logic before the action executes
        Debug.WriteLine("Action Method Executing: " + actionContext.ActionDescriptor.ActionName);
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        // Custom logic after the action executes
        Debug.WriteLine("Action Method Executed: " + actionExecutedContext.ActionContext.ActionDescriptor.ActionName);
    }
}

// Applying the custom action filter to a controller
public class SampleController : ApiController
{
    [CustomActionFilter]
    public IHttpActionResult Get()
    {
        return Ok("Hello, world!");
    }
}

14. Explain the role of HttpClient in Web API.

HttpClient is a class provided by the .NET framework that allows developers to send HTTP requests and receive HTTP responses. It is commonly used in Web API applications to interact with external services or APIs. HttpClient supports various HTTP methods such as GET, POST, PUT, DELETE, and more. It also provides features like handling cookies, setting headers, and managing timeouts.

Example:

using System;
using System.Net.Http;
using System.Threading.Tasks;

public class ApiService
{
    private static readonly HttpClient client = new HttpClient();

    public async Task<string> GetDataAsync(string url)
    {
        HttpResponseMessage response = await client.GetAsync(url);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

In this example, the ApiService class uses HttpClient to send a GET request to a specified URL and returns the response content as a string. The EnsureSuccessStatusCode method throws an exception if the HTTP response is not successful, ensuring that errors are properly handled.

15. How do you implement logging in Web API?

Logging is a crucial aspect of any Web API as it helps in monitoring, debugging, and maintaining the application. In C#, logging can be implemented using various libraries, with Serilog being one of the most popular choices due to its simplicity and flexibility.

To implement logging in a Web API using Serilog, follow these steps:

  • Install the Serilog and Serilog.Extensions.Logging packages via NuGet.
  • Configure Serilog in the Program.cs or Startup.cs file.
  • Inject the logger into your controllers or services.

Example:

// Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Serilog;

public class Program
{
    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .CreateLogger();

        try
        {
            Log.Information("Starting web host");
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseSerilog() // Add this line
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

In your controller:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        _logger.LogInformation("Fetching weather forecast data");
        // Your logic here
    }
}
Previous

15 Visualforce Interview Questions and Answers

Back to Interview
Next

15 Computer System Validation Interview Questions and Answers