microsoft3 min read

ASP.NET Web API Tutorial: Build RESTful Services from Scratch (2026)

ASP.NET Web API Tutorial: Build RESTful Services from Scratch (2026)

Published:  |  Category: Microsoft  |  Reading time: ~15 min
ASP.NET Web API Tutorial: Build RESTful Services from Scratch (2026)

I have built REST APIs with Node.js, Python, Java, and Go, but ASP.NET Web API remains my favorite for enterprise-grade services. The combination of strong typing, built-in validation, OpenAPI integration, and industrial-strength middleware makes it the most productive framework for building APIs that need to scale.

ASP.NET Core Web API is a framework for building HTTP APIs following RESTful principles. It supports JSON and XML, attribute-based routing, model binding and validation, Swagger/OpenAPI integration, and runs cross-platform on Windows, Linux, and macOS.

Setting Up the Project and Routing

The dotnet new webapi template scaffolds a project with a controller and OpenAPI support. Use [ApiController] and [Route] attributes. Action methods map to HTTP verbs — [HttpGet], [HttpPost], [HttpPut], [HttpDelete]. Attribute routing gives precise URL control.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
    .AddJsonOptions(o=>o.JsonSerializerOptions.PropertyNamingPolicy=
        System.Text.Json.JsonNamingPolicy.CamelCase);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.MapControllers();
app.Run();

Model Binding, Validation, and Formatting

Model binding maps request data to parameters. Use [FromBody], [FromQuery], [FromRoute] to disambiguate. [ApiController] auto-returns 400 on validation failure. DataAnnotations like [Required], [StringLength] handle validation. FluentValidation is a popular alternative.

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet("{id:int}")]
    public async Task> GetById(int id)
    {
        var product = await _service.GetByIdAsync(id);
        if (product == null) return NotFound();
        return Ok(product);
    }
}

API Versioning Strategies

Support multiple API versions simultaneously. URL path versioning (/api/v1/products) is most common. Configure versioning in services and apply [ApiVersion] attributes. Each version gets its own Swagger document. Deprecate old versions gracefully.

builder.Services.AddApiVersioning(options=>
{
    options.DefaultApiVersion = new ApiVersion(1,0);
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.ReportApiVersions = true;
    options.ApiVersionReader = new UrlSegmentApiVersionReader();
});
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class ProductsController : ControllerBase {}

Authentication, Authorization, and Security

JWT bearer authentication is standard for modern APIs. Configure middleware to validate tokens. Authorization policies control endpoint access. Use [Authorize] on controllers or actions. Always use HTTPS, enable CORS explicitly, and implement rate limiting.

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options=>{
        options.Authority="https://login.microsoftonline.com/{tenant}";
        options.Audience="api://{client-id}";
    });
builder.Services.AddAuthorization(options=>{
    options.AddPolicy("RequireAdmin",policy=>
        policy.RequireRole("admin").RequireClaim("scope","api.write"));
});

Exception Handling, Logging, and Health Checks

Use custom middleware or ProblemDetails for structured errors. Log with correlation IDs. Serilog or Application Insights provide structured logging. Health checks expose /health endpoints for monitoring systems. Register checks for databases and external services.

app.UseExceptionHandler(exceptionHandlerApp=>
{
    exceptionHandlerApp.Run(async context=>
    {
        context.Response.StatusCode=500;
        context.Response.ContentType="application/problem+json";
        await context.Response.WriteAsJsonAsync(new ProblemDetails
        {
            Title="An error occurred",Status=500
        });
    });
});

Swagger, OpenAPI, and Client Generation

Swashbuckle generates OpenAPI specs from controller metadata — routes, parameters, response types. Swagger UI provides interactive documentation. Generate client libraries with NSwag, AutoRest, or OpenAPI Generator.

builder.Services.AddSwaggerGen(c=>
{
    c.SwaggerDoc("v1",new OpenApiInfo{Title="Product API",Version="v1"});
    c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory,"MyApi.xml"));
    c.AddSecurityDefinition("Bearer",new OpenApiSecurityScheme
    {
        In=ParameterLocation.Header,Name="Authorization",
        Type=SecuritySchemeType.Http,Scheme="bearer"
    });
});

Frequently Asked Questions

What is the difference between ASP.NET Web API and ASP.NET Core Web API?

ASP.NET Web API (legacy) runs only on Windows. ASP.NET Core Web API is cross-platform, open-source, and modular. Core is recommended for all new projects.

How do I handle file uploads in Web API?

Use IFormFile as an action parameter with [FromForm]. For multiple files, use IFormFileCollection. Configure maximum file size in request body size limit options.

Should I version my API from day one?

Yes. Having versioning infrastructure from the start makes it easy to evolve your API without breaking existing clients.

How does Web API handle CORS?

Add CORS services and middleware. Configure policies specifying allowed origins, methods, and headers. Apply globally or per-controller with [EnableCors].

Originally published on Ayodhyyya. Last updated June 1, 2026.