How to create REST APIs in ASP.NET Core? Follow :
Creating REST APIs in ASP.NET Core is straightforward using controllers or minimal
APIs.
Example: Traditional Controller-Based API
dotnet new webapi -n MyApi
Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
Controller:
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
[HttpGet]
public IActionResult GetAll() => Ok(new[] { "Laptop", "Phone"
});
β You get RESTful endpoints automatically (GET /api/products).
π§± 2. What is the [ApiController] attribute?
[ApiController] simplifies building APIs by adding smart defaults:
- Automatic model validation β 400 Bad Request on invalid models
- Automatic [FromBody], [FromQuery], etc. inference
Follow :
- ProblemDetails JSON response for errors
Example:
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
[HttpPost]
public IActionResult CreateOrder(Order order)
if (!ModelState.IsValid)
return BadRequest(ModelState);
return CreatedAtAction(nameof(CreateOrder), new { id = 1 },
order);
π¦ 3. How does content negotiation work?
Content negotiation allows clients to request responses in a specific format (JSON, XML,
etc.) using the Accept header.
ASP.NET Core automatically picks the best formatter:
GET /api/products
Accept: application/json
Response β JSON
GET /api/products
Accept: application/xml
Response β XML (if XML formatter is added)
Follow :
Enable XML Support:
builder.Services.AddControllers()
.AddXmlSerializerFormatters();
π§ 4. How to handle versioning in APIs?
You can version APIs to maintain backward compatibility using the
Microsoft.AspNetCore.Mvc.Versioning package.
Install:
dotnet add package Microsoft.AspNetCore.Mvc.Versioning
Configure:
builder.Services.AddApiVersioning(options =>
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
});
Use in controllers:
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/products")]
[ApiController]
public class ProductsV1Controller : ControllerBase
[HttpGet]
public IActionResult Get() => Ok("Version 1");
β 5. What is ProblemDetails?
Follow :
ProblemDetails is a standardized JSON structure for API error responses (RFC 7807).
Example Output:
"type": "
"title": "Resource not found",
"status": 404,
"detail": "Product with ID 5 was not found"
Usage:
return NotFound(new ProblemDetails
Title = "Product not found",
Status = StatusCodes.Status404NotFound,
Detail = "The product ID 5 does not exist."
});
π¦ 6. How to return custom HTTP status codes?
You can use built-in helpers from ControllerBase:
Method Status
Code
Ok() 200
Created() /
CreatedAtAction()
201
NoContent() 204
BadRequest() 400
Unauthorized() 401
Follow :
NotFound() 404
StatusCode(500) Custom
Example:
return StatusCode(503, "Service temporarily unavailable");
π 7. How to implement pagination in APIs?
Pagination helps manage large datasets efficiently.
Example:
[HttpGet]
public IActionResult GetProducts([FromQuery] int page = 1,
[FromQuery] int size = 10)
var data = _context.Products
.Skip((page - 1) * size)
.Take(size)
.ToList();
var totalCount = _context.Products.Count();
Response.Headers.Add("X-Total-Count", totalCount.ToString());
return Ok(data);
β Supports GET /api/products?page=2&size=5.
π 8. How to secure APIs with JWT tokens?
Use JWT (JSON Web Token) authentication for stateless security.
Follow :
Setup in Program.cs:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationS
cheme)
.AddJwtBearer(options =>
options.TokenValidationParameters = new
TokenValidationParameters
ValidateIssuer = true,
ValidIssuer = "
ValidateAudience = true,
ValidAudience = "
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes("super-secret-key"))
});
Then protect controllers:
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
[HttpGet]
public IActionResult GetOrders() => Ok("Secure data");
β‘ 9. What is rate limiting in .NET 8?
.NET 8 introduces built-in rate limiting middleware to control API request rates.
Example:
builder.Services.AddRateLimiter(options =>
Follow :
options.AddFixedWindowLimiter("fixed", opt =>
opt.PermitLimit = 5; // 5 requests
opt.Window = TimeSpan.FromSeconds(10); // per 10 seconds
opt.QueueLimit = 0;
});
});
var app = builder.Build();
app.UseRateLimiter();
app.MapGet("/api/data", () => "Hello")
.RequireRateLimiting("fixed");
β Prevents abuse or DDoS attacks by throttling requests.
π¨ 10. How do you handle exceptions in APIs?
Use global exception handling middleware instead of try/catch everywhere.
Example:
app.UseExceptionHandler("/error");
app.Map("/error", (HttpContext context) =>
var exception =
context.Features.Get<IExceptionHandlerFeature>()?.Error;
return Results.Problem(title: "Unexpected error", detail:
exception?.Message);
});
Or write a custom middleware for consistent error formatting.
Follow :
π§Ύ 11. How to use Swagger / OpenAPI?
Swagger generates interactive API documentation automatically.
Setup:
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
app.UseSwagger();
app.UseSwaggerUI();
Run β Navigate to
β You can test endpoints directly from the browser.
π§° 12. What is NSwag or Swashbuckle?
Both tools generate OpenAPI/Swagger documentation, but with slight differences:
Tool Description
Swashbuckle.AspNetCor
Most common; adds Swagger UI, docs, and JSON schema
NSwag Adds extra features like client SDK generation for
C#/TypeScript
Example (NSwag client generation):
Follow :
nswag openapi2csclient
/input:
/output:Client.cs
π€ 13. How to upload files via Web API?
Use IFormFile for file uploads.
Controller Example:
[HttpPost("upload")]
public async Task<IActionResult> UploadFile(IFormFile file)
if (file == null || file.Length == 0)
return BadRequest("No file uploaded.");
var path = Path.Combine("wwwroot/uploads", file.FileName);
using var stream = new FileStream(path, FileMode.Create);
await file.CopyToAsync(stream);
return Ok(new { file.FileName, file.Length });
Client sends multipart/form-data POST requests.
π 14. How to implement CORS?
CORS (Cross-Origin Resource Sharing) allows requests from other domains (e.g., frontend
apps).
Enable in Program.cs:
builder.Services.AddCors(options =>
Follow :
options.AddPolicy("AllowReactApp",
policy => policy.WithOrigins("
.AllowAnyHeader()
.AllowAnyMethod());
});
var app = builder.Build();
app.UseCors("AllowReactApp");
β Now your React or Angular frontend can call your API safely.
π 15. Whatβs new in .NET 8 Minimal APIs?
Minimal APIs let you build lightweight REST endpoints without controllers β great for
microservices.
Example:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/products", () => new[] { "Phone", "Tablet" });
app.MapPost("/products", (Product product) =>
Results.Created($"/products/{product.Id}", product));
app.Run();
New in .NET 8:
- Route groups for grouping endpoints
- Input validation with [Validate] attributes
- Enhanced OpenAPI (Swagger) support
- Rate limiting, Authorization, and Filters integration
Follow :
- Typed results for consistent HTTP responses
β Minimal APIs now rival traditional controllers for small, fast APIs.
Performance & Caching