Building a RESTful API with ASP.NET Core: Step-by-Step Guide

📋 Table of Contents

  1. Introduction

  2. Prerequisites

  3. Creating the Project

  4. Understanding the Project Structure

  5. Configuration Files

    • appsettings.json

    • launchSettings.json

  6. Creating DTOs

  7. Creating Routes and Controllers

  8. Implementing JWT Authentication

    • What is JWT?

    • JWT Configuration

    • Token Generation

    • AuthController

    • Protecting Endpoints

    • Example JWT Token

    • External Decoding

  9. API Versioning

  10. Documenting with Swagger

    • What is Swagger?

    • Swagger Configuration

  11. Testing with Postman

  12. Conclusion


🧾 1. Introduction

In this article, you’ll learn how to build a modern RESTful API using ASP.NET Core, covering essential concepts like routes, controllers, DTOs, API versioning, Swagger for documentation, and JWT authentication.

Perfect for developers starting with .NET APIs or looking to reinforce best practices in architecture and security.


🛠️ 2. Prerequisites

  • .NET SDK 7.0 or higher

  • Visual Studio or VS Code

  • Basic understanding of C# and HTTP

  • Postman or another API testing tool


🛠️3. Creating the Project

Create a new ASP.NET Core Web API project:

dotnet new webapi -n MyApiProject
cd MyApiProject

This will generate a basic structure with a sample controller.


🧩 4. Understanding the Project Structure

Key folders and files:

  • Controllers/: where your API controllers live

  • Program.cs and Startup.cs (or just Program.cs in .NET 6+)

  • appsettings.json: settings like JWT keys

  • launchSettings.json: local run profile


⚙️ 5. Configuration Files

appsettings.json

{
  "Jwt": {
    "Key": "my-super-secret-key",
    "Issuer": "MyApiIssuer",
    "Audience": "MyApiAudience"
  }
}

Explanation:
Stores JWT settings like secret key, issuer, and audience used for token validation.


launchSettings.json

"profiles": {
  "MyApiProject": {
    "applicationUrl": "https://localhost:5001;http://localhost:5000",
    "environmentVariables": {
      "ASPNETCORE_ENVIRONMENT": "Development"
    }
  }
}

Explanation:
Defines how the app runs locally, including URLs and environment mode.


📦 6. Creating DTOs

LoginDto

public class LoginDto
{
    public string Username { get; set; }
    public string Password { get; set; }
}

Explanation:
Receives login credentials from the client during authentication.


ProductDto

public class ProductDto
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Explanation:
Represents product data returned by the API.


🧭 7. Creating Routes and Controllers

ProductsController

[ApiController]
[Route("api/v1/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet]
    [Authorize]
    public IActionResult GetAll()
    {
        var products = new List<ProductDto>
        {
            new ProductDto { Id = 1, Name = "Product A" },
            new ProductDto { Id = 2, Name = "Product B" }
        };

        return Ok(products);
    }
}

Explanation:
Defines a GET endpoint at /api/v1/products that returns a list of products. The [Authorize] attribute ensures only authenticated users can access it.


🔐 8. Implementing JWT Authentication

What is JWT?

JWT (JSON Web Token) is a secure way to transmit user identity and claims between client and server.


JWT Configuration (Program.cs)

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "MyApiIssuer",
            ValidAudience = "MyApiAudience",
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes("my-super-secret-key"))
        };
    });

builder.Services.AddAuthorization();

app.UseAuthentication();
app.UseAuthorization();

Explanation:
Configures JWT authentication and authorization. Tokens are validated based on issuer, audience, expiration, and signature.


Token Generation Method

private string GenerateJwtToken()
{
    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("my-super-secret-key"));
    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

    var claims = new[]
    {
        new Claim(ClaimTypes.Name, "admin"),
        new Claim(ClaimTypes.Role, "Administrator")
    };

    var token = new JwtSecurityToken(
        issuer: "MyApiIssuer",
        audience: "MyApiAudience",
        claims: claims,
        expires: DateTime.Now.AddHours(1),
        signingCredentials: credentials
    );

    return new JwtSecurityTokenHandler().WriteToken(token);
}

Explanation:
Generates a JWT token with user claims and expiration. Uses HMAC SHA256 to sign the token securely.


AuthController

[ApiController]
[Route("api/v1/[controller]")]
public class AuthController : ControllerBase
{
    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginDto login)
    {
        if (login.Username == "admin" && login.Password == "123")
        {
            var token = GenerateJwtToken();
            return Ok(new { token });
        }

        return Unauthorized();
    }

    private string GenerateJwtToken()
    {
        // Same method as above
    }
}

Explanation:
Handles login requests. If credentials are valid, returns a JWT token. Otherwise, returns 401 Unauthorized.


Example JWT Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Explanation:
This is a sample JWT token. It contains encoded user info and is used to access protected endpoints.


External Decoding

Use jwt.io to decode and inspect your token.

Explanation:
You can view the token’s header, payload (claims), and signature to verify its contents.


📚 10. Documenting with Swagger

Swagger Configuration

builder.Services.AddSwaggerGen();

app.UseSwagger();
app.UseSwaggerUI();

Explanation:
Enables Swagger UI at /swagger, allowing you to explore and test your API interactively.


🧪 11. Testing with Postman

  1. Send POST to /api/v1/auth/login with:
{
  "username": "admin",
  "password": "123"
}
  1. Copy the token from the response.

  2. Send GET to /api/v1/products with header:

Authorization: Bearer <your_token_here>

Explanation:
This simulates a login and authenticated request using JWT. Postman helps test endpoints easily.


🏁 12. Conclusion

You now have a fully functional ASP.NET Core API with:

  • Clean architecture

  • JWT authentication

  • API versioning

  • Swagger documentation

This setup is perfect for scalable backend systems and can be extended with databases, role-based access, and more.

#AspNetCore #DotNet #CSharp #DotNetDev #DotNetCommunity #WebAPI #RESTAPI #BackendDevelopment #APIDevelopment #Microservices #JWT #Authentication #SecureAPI #TokenBasedAuth #Swagger #OpenAPI #CleanCode #SoftwareArchitecture #DevTips #CodeNewbie #LearnToCode #100DaysOfCode #TechTutorial

0
Subscribe to my newsletter

Read articles from Johnny Hideki Kinoshita de Faria directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Johnny Hideki Kinoshita de Faria
Johnny Hideki Kinoshita de Faria

Technology professional with over 15 years of experience delivering innovative, scalable, and secure solutions — especially within the financial sector. I bring deep expertise in Oracle PL/SQL (9+ years), designing robust data architectures that ensure performance and reliability. On the back-end side, I’ve spent 6 years building enterprise-grade applications using .NET, applying best practices like TDD and clean code to deliver high-quality solutions. In addition to my backend strengths, I have 6 years of experience with PHP and JavaScript, allowing me to develop full-stack web applications that combine strong performance with intuitive user interfaces. I've led and contributed to projects involving digital account management, integration of VISA credit and debit transactions, modernization of payment systems, financial analysis tools, and fraud prevention strategies. Academically, I hold a postgraduate certificate in .NET Architecture and an MBA in IT Project Management, blending technical skill with business acumen. Over the past 6 years, I’ve also taken on leadership roles — managing teams, mentoring developers, and driving strategic initiatives. I'm fluent in agile methodologies and make consistent use of tools like Azure Boards to coordinate tasks and align team performance with delivery goals.