Your First Web Application
π― What You'll Learn
- Creating an ASP.NET Core Web API project
- Understanding the generated project structure
- Running your first web application
- Testing API endpoints with Swagger
- Creating your first controller
- Understanding routing and HTTP methods
- Building a simple InvenTrack product API
- Testing with browser and curl
Creating Your First Web API
Let's create a simple Web API for InvenTrack. We'll start with a minimal API that manages products.
Step 1: Create the Project
# Navigate to your projects folder
cd C:\Users\YourName\Projects
# Create a new Web API project
dotnet new webapi -n InvenTrack.Api
# Navigate into the project
cd InvenTrack.Api
The webapi template created a complete ASP.NET Core Web API project with:
β’ Project file (.csproj)
β’ Program.cs (application entry point)
β’ appsettings.json (configuration)
β’ A sample WeatherForecast controller
β’ Swagger/OpenAPI support
Step 2: Explore the Project Structure
InvenTrack.Api/
βββ Controllers/
β βββ WeatherForecastController.cs # Sample controller
βββ Properties/
β βββ launchSettings.json # Launch configuration
βββ appsettings.json # App configuration
βββ appsettings.Development.json # Dev-specific config
βββ InvenTrack.Api.csproj # Project file
βββ Program.cs # Application entry point
βββ WeatherForecast.cs # Sample model
Step 3: Run the Application
dotnet run
You'll see output like:
Building...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
Your web API is now running! It's listening on:
β’ HTTP: http://localhost:5000
β’ HTTPS: https://localhost:5001
Open your browser and navigate to https://localhost:5001/swagger
Exploring Swagger UI
Swagger (OpenAPI) provides an interactive API documentation interface. When you navigate
to https://localhost:5001/swagger, you'll see:
- All available API endpoints
- HTTP methods (GET, POST, PUT, DELETE)
- Request/response models
- Interactive "Try it out" buttons
Testing the Sample Endpoint
- Click on GET /WeatherForecast
- Click "Try it out"
- Click "Execute"
- See the JSON response
[
{
"date": "2024-12-10",
"temperatureC": 25,
"temperatureF": 76,
"summary": "Warm"
},
{
"date": "2024-12-11",
"temperatureC": 18,
"temperatureF": 64,
"summary": "Cool"
}
]
Understanding the Sample Code
WeatherForecast.cs - The Model
namespace InvenTrack.Api;
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
This is a simple data model (DTO - Data Transfer Object) representing weather data.
WeatherForecastController.cs - The Controller
using Microsoft.AspNetCore.Mvc;
namespace InvenTrack.Api.Controllers;
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild",
"Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
Key Attributes Explained
| Attribute | Purpose |
|---|---|
[ApiController] |
Enables API-specific behaviors (auto model validation, etc.) |
[Route("[controller]")] |
Sets base route to controller name (e.g., /WeatherForecast) |
[HttpGet] |
Maps method to HTTP GET requests |
Creating Your First InvenTrack Endpoint
Let's create a simple Products API for InvenTrack. We'll build it step by step.
Step 1: Create the Product Model
Create a new file Product.cs in the project root:
namespace InvenTrack.Api;
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Sku { get; set; } = string.Empty;
public decimal Price { get; set; }
public int QuantityInStock { get; set; }
public string? Category { get; set; }
}
Step 2: Create the Products Controller
Create a new file ProductsController.cs in the Controllers folder:
using Microsoft.AspNetCore.Mvc;
namespace InvenTrack.Api.Controllers;
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
// In-memory product list (temporary - we'll use a database later)
private static readonly List<Product> Products = new()
{
new Product
{
Id = 1,
Name = "Laptop - Dell XPS 15",
Sku = "LAP-DELL-XPS15",
Price = 1299.99m,
QuantityInStock = 15,
Category = "Electronics"
},
new Product
{
Id = 2,
Name = "Wireless Mouse",
Sku = "ACC-MOUSE-001",
Price = 29.99m,
QuantityInStock = 150,
Category = "Accessories"
},
new Product
{
Id = 3,
Name = "USB-C Cable",
Sku = "CAB-USBC-2M",
Price = 12.99m,
QuantityInStock = 300,
Category = "Cables"
}
};
// GET: api/products
[HttpGet]
public ActionResult<IEnumerable<Product>> GetProducts()
{
return Ok(Products);
}
// GET: api/products/1
[HttpGet("{id}")]
public ActionResult<Product> GetProduct(int id)
{
var product = Products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
return NotFound(new { message = $"Product with ID {id} not found" });
}
return Ok(product);
}
// POST: api/products
[HttpPost]
public ActionResult<Product> CreateProduct(Product product)
{
// Generate new ID
product.Id = Products.Max(p => p.Id) + 1;
Products.Add(product);
return CreatedAtAction(
nameof(GetProduct),
new { id = product.Id },
product
);
}
// PUT: api/products/1
[HttpPut("{id}")]
public IActionResult UpdateProduct(int id, Product product)
{
var existingProduct = Products.FirstOrDefault(p => p.Id == id);
if (existingProduct == null)
{
return NotFound();
}
existingProduct.Name = product.Name;
existingProduct.Sku = product.Sku;
existingProduct.Price = product.Price;
existingProduct.QuantityInStock = product.QuantityInStock;
existingProduct.Category = product.Category;
return NoContent();
}
// DELETE: api/products/1
[HttpDelete("{id}")]
public IActionResult DeleteProduct(int id)
{
var product = Products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
return NotFound();
}
Products.Remove(product);
return NoContent();
}
}
This is a complete CRUD API (Create, Read, Update, Delete) for products:
β’ GET /api/products - List all products
β’ GET /api/products/{id} - Get single product
β’ POST /api/products - Create new product
β’ PUT /api/products/{id} - Update product
β’ DELETE /api/products/{id} - Delete product
Testing Your API
Method 1: Using Swagger
- Run the app:
dotnet run - Navigate to
https://localhost:5001/swagger - You'll see your Products endpoints listed
- Try each endpoint:
- GET /api/products - See all products
- GET /api/products/1 - Get product with ID 1
- POST /api/products - Create a new product
Method 2: Using curl
# Get all products
curl https://localhost:5001/api/products
# Get single product
curl https://localhost:5001/api/products/1
# Create new product
curl -X POST https://localhost:5001/api/products \
-H "Content-Type: application/json" \
-d '{
"name": "Mechanical Keyboard",
"sku": "KEY-MECH-001",
"price": 89.99,
"quantityInStock": 50,
"category": "Accessories"
}'
Method 3: Using Browser
For GET requests, simply navigate to:
https://localhost:5001/api/productshttps://localhost:5001/api/products/1
Understanding HTTP Status Codes
Your API returns different status codes based on the result:
| Status Code | Method | Meaning |
|---|---|---|
| 200 OK | Ok() |
Request succeeded, returning data |
| 201 Created | CreatedAtAction() |
Resource created successfully |
| 204 No Content | NoContent() |
Request succeeded, no data to return |
| 404 Not Found | NotFound() |
Resource doesn't exist |
| 400 Bad Request | BadRequest() |
Invalid request data |
Understanding Routing
Route Templates
// Controller-level route
[Route("api/[controller]")]
// Becomes: /api/products
// Action-level route with parameter
[HttpGet("{id}")]
// Becomes: /api/products/{id}
// Custom route
[HttpGet("search/{term}")]
// Becomes: /api/products/search/{term}
Route Constraints
// ID must be an integer
[HttpGet("{id:int}")]
// ID must be a GUID
[HttpGet("{id:guid}")]
// Multiple constraints
[HttpGet("{id:int:min(1)}")]
Key Takeaways
- Create Web APIs with
dotnet new webapi - Controllers handle HTTP requests and return responses
[ApiController]enables API-specific behaviors[Route]defines URL patterns- HTTP method attributes:
[HttpGet],[HttpPost],[HttpPut],[HttpDelete] - ActionResult<T> allows returning both data and status codes
Ok(),NotFound(),CreatedAtAction()return appropriate status codes- Swagger provides interactive API documentation
- Route parameters like
{id}are automatically bound to method parameters - ASP.NET Core automatically serializes objects to JSON
You've built your first working Web API! In the next section, we'll do a deep dive into Program.csβunderstanding how ASP.NET Core applications start up, the middleware pipeline, dependency injection configuration, and how everything comes together.