ASP.NET Core Basics: Web API, MVC, Routing & Middleware in C#
1. ASP.NET Core Basics
Q: What is ASP.NET Core?
ASP.NET Core is a cross-platform, high-performance, open-source framework for building modern web applications and APIs using C#. It supports building web APIs, MVC (Model-View-Controller) applications, and other web-based solutions, with features like dependency injection, middleware, and routing.
Q: Why is ASP.NET Core important?
- Cross-platform: Runs on Windows, macOS, and Linux.
- High performance: Optimized for scalability and speed.
- Flexible: Supports Web APIs, MVC, Razor Pages, and Blazor.
- Integrated: Built-in dependency injection, logging, and configuration.
- Modern: Supports cloud deployment, microservices, and containerization.
Q: How does ASP.NET Core differ from C/C++ for web development?
- ASP.NET Core: Managed, type-safe, provides built-in web server (Kestrel), routing, middleware, and MVC patterns. Integrated with .NET ecosystem.
- C/C++: No native web framework; requires third-party libraries (e.g., Boost.Beast, libmicrohttpd) or manual server implementation. Complex and error-prone.
- C# Advantage: Simplified, secure, with robust tooling and Visual Studio integration.
2. Building Web APIs and MVC Apps
Q: What is a Web API in ASP.NET Core?
A Web API is a RESTful service that exposes endpoints to handle HTTP requests (e.g., GET, POST) and return data (e.g., JSON, XML). In ASP.NET Core, Web APIs are built using controllers or minimal APIs, leveraging attributes like [HttpGet] and [HttpPost].
Q: What is an MVC app in ASP.NET Core?
An MVC (Model-View-Controller) app follows the MVC pattern:
- Model: Represents data and business logic.
- View: Renders the UI (e.g., Razor views for HTML).
- Controller: Handles requests, interacts with models, and returns views or data.
- MVC apps are ideal for server-rendered web applications with dynamic UIs.
Q: How do you build a Web API and MVC app in ASP.NET Core?
- Web API: Create a controller with
[ApiController]and define endpoints with HTTP attributes. Use minimal APIs for simpler scenarios. - MVC App: Create models, views (Razor
.cshtmlfiles), and controllers with[Controller]. Configure routing to map URLs to actions. - Both use dependency injection, middleware, and routing for request handling.
Q: Can you give an example of a Web API and MVC app in ASP.NET Core?
Web API Example (Minimal API):
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Register services
builder.Services.AddSingleton<IUserService, UserService>();
var app = builder.Build();
// Web API endpoints (Minimal API)
app.MapGet("/api/users/{id}", (int id, IUserService userService) =>
{
var user = userService.GetUser(id);
return user != null ? Results.Ok(user) : Results.NotFound();
});
app.MapPost("/api/users", (User user, IUserService userService) =>
{
userService.AddUser(user);
return Results.Created($"/api/users/{user.Id}", user);
});
app.Run();
// Model
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
// Service
public interface IUserService
{
User? GetUser(int id);
void AddUser(User user);
}
public class UserService : IUserService
{
private readonly List<User> _users = new();
public User? GetUser(int id) => _users.FirstOrDefault(u => u.Id == id);
public void AddUser(User user)
{
user.Id = _users.Count + 1;
_users.Add(user);
}
}
Description: A minimal Web API with GET and POST endpoints to retrieve and add users. Uses dependency injection for the UserService.
Usage:
GET http://localhost:5000/api/users/1: Returns a user or 404.POST http://localhost:5000/api/userswith JSON{ "Name": "Krishna" }: Creates a user and returns 201.
MVC App Example:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
// Add MVC services
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton<IUserService, UserService>();
var app = builder.Build();
// Configure middleware
app.UseRouting();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
// Model
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
// Service
public interface IUserService
{
List<User> GetUsers();
void AddUser(User user);
}
public class UserService : IUserService
{
private readonly List<User> _users = new();
public List<User> GetUsers() => _users;
public void AddUser(User user)
{
user.Id = _users.Count + 1;
_users.Add(user);
}
}
// Controller
public class HomeController : Controller
{
private readonly IUserService _userService;
public HomeController(IUserService userService)
{
_userService = userService;
}
public IActionResult Index()
{
var users = _userService.GetUsers();
return View(users);
}
[HttpPost]
public IActionResult AddUser(User user)
{
if (ModelState.IsValid)
{
_userService.AddUser(user);
return RedirectToAction("Index");
}
return View("Index", _userService.GetUsers());
}
}
@model List<User>
<!DOCTYPE html>
<html>
<head>
<title>User List</title>
</head>
<body>
<h2>User List</h2>
<form asp-action="AddUser" method="post">
<input name="Name" placeholder="Enter name" />
<button type="submit">Add User</button>
</form>
<ul>
@foreach (var user in Model)
{
<li>@user.Name (ID: @user.Id)</li>
}
</ul>
</body>
</html>
Description: An MVC app with a home page displaying a user list and a form to add users. Uses Razor for views and dependency injection for the UserService.
Usage:
GET http://localhost:5000: Displays the user list and form.POST http://localhost:5000/Home/AddUserwith form dataName=Krishna: Adds a user and refreshes the list.
3. Routing, Middleware, and Controllers
Q: What is routing in ASP.NET Core?
Routing maps incoming HTTP requests to specific endpoints (e.g., controller actions or minimal API handlers) based on URL patterns. ASP.NET Core supports:
- Conventional Routing: Defines patterns (e.g.,
{controller}/{action}/{id?}) for MVC. - Attribute Routing: Uses attributes (e.g.,
[Route("api/users")]) in controllers or minimal APIs. - Routing is configured in the middleware pipeline.
Q: What is middleware in ASP.NET Core?
Middleware is a chain of components that process HTTP requests and responses. Each component can handle the request, modify it, or pass it to the next component. Common middleware includes:
UseRouting:Matches requests to endpoints.UseAuthorization:Enforces security.UseStaticFiles:Serves static files (e.g., CSS, images).- Middleware is configured in
Program.csusingapp.Use*andapp.Run.
Q: What are controllers in ASP.NET Core?
Controllers are classes (inheriting from Controller or ControllerBase) that handle HTTP requests in MVC or Web API applications. They contain action methods (e.g., Index, Get) marked with HTTP attributes (e.g., [HttpGet]) to process requests and return responses (e.g., views, JSON).
Q: Can you give an example of routing, middleware, and controllers in ASP.NET Core?
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Register services
builder.Services.AddControllers();
builder.Services.AddSingleton<IUserService, UserService>();
var app = builder.Build();
// Middleware pipeline
app.UseRouting();
app.Use(async (context, next) =>
{
Console.WriteLine($"Request: {context.Request.Path}");
await next.Invoke();
});
app.UseEndpoints(endpoints => endpoints.MapControllers());
app.Run();
// Model
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
// Service
public interface IUserService
{
User? GetUser(int id);
void AddUser(User user);
}
public class UserService : IUserService
{
private readonly List<User> _users = new();
public User? GetUser(int id) => _users.FirstOrDefault(u => u.Id == id);
public void AddUser(User user)
{
user.Id = _users.Count + 1;
_users.Add(user);
}
}
// Controller
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService;
}
[HttpGet("{id}")]
public IActionResult GetUser(int id)
{
var user = _userService.GetUser(id);
return user != null ? Ok(user) : NotFound();
}
[HttpPost]
public IActionResult AddUser([FromBody] User user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_userService.AddUser(user);
return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
}
}
Description: A Web API with:
- Routing: Attribute routing (
[Route("api/[controller]")]), maps/api/users/{id}to actions. - Middleware: Custom middleware logs request paths, followed by routing and endpoint middleware.
- Controller:
UsersControllerhandles GET and POST requests with dependency injection.
Usage:
GET http://localhost:5000/api/users/1: Returns a user or 404.POST http://localhost:5000/api/userswith JSON{ "Name": "Krishna" }: Creates a user and returns 201.
Output (console):
Request: /api/users/1
Q: How do routing, middleware, and controllers in ASP.NET Core differ from C/C++?
- ASP.NET Core: Provides built-in routing, middleware pipeline, and controller-based request handling, managed and type-safe.
- C/C++: No native web framework; requires manual HTTP parsing or libraries (e.g., Crow, Poco), with manual routing and request handling.
- C# Advantage: Simplified, secure, with integrated .NET features and Visual Studio support.
4. Common Mistakes & Best Practices
Q: Common mistakes?
Routing:
- Misconfiguring routes, causing 404 errors (e.g., missing
[Route]or incorrect patterns). - Overlapping route patterns, leading to ambiguous matches.
Middleware:
- Incorrect middleware order, causing issues (e.g.,
UseAuthorizationbeforeUseRouting). - Writing blocking middleware, impacting performance.
Controllers:
- Not validating models, leading to invalid data processing.
- Overloading controllers with business logic instead of using services.
- Forgetting
[ApiController]for Web APIs, missing features like model validation.
Q: Best practices?
Routing:
- Use attribute routing for Web APIs (
[Route]), conventional routing for MVC. - Keep route patterns clear and non-overlapping.
- Use route constraints (e.g.,
{id:int}) for type safety.
Middleware:
- Order middleware correctly (e.g.,
UseRouting,UseAuthorization,UseEndpoints). - Write lightweight middleware, avoiding heavy processing.
- Use custom middleware for cross-cutting concerns (e.g., logging, error handling).
Controllers:
- Use
[ApiController]for Web APIs to enable automatic validation and problem details. - Keep controllers thin, delegating logic to services.
- Return appropriate
IActionResulttypes (e.g.,Ok,NotFound,BadRequest). - Use dependency injection for services and repositories.
General:
- Validate models with data annotations or custom validation.
- Use
async/awaitfor I/O-bound operations (e.g., database, HTTP calls). - Implement error handling middleware for consistent error responses.
- Document APIs with XML comments or OpenAPI (Swagger).
- Test endpoints with unit tests (for logic) and integration tests (for APIs).