Mid MVC

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

More from ASP.NET Core MVC Tutorial

All questions for this course