A brief introduction to ASP.NET Core using C#12 and .NET 8

Overview

High-performance, cloud-based web applications can be built with ASP.NET Core, a modern framework for cross-platform development. In addition to offering greater flexibility, performance, and compatibility across different operating systems, it represents an evolutionary change from the traditional ASP.NET framework.

Key Features of ASP.NET Core

  1. Cross-Platform Support:  This cross-platform capability allows developers to build and deploy applications on different platforms, such as Windows, Linux, and macOS.
  2. Unified Framework:  Through its unified programming model, ASP.NET Core combines the best features of ASP.NET MVC and ASP.NET Web API to simplify the development process.
  3. Performance:  As a result of its modular and lightweight architecture, ASP.NET Core provides excellent performance and scalability.
  4. Dependency Injection:  With dependency injection (DI), ASP.NET Core promotes loose coupling and increases testability. Object lifetimes and dependencies are simplified with DI.
  5. Modular Design:  In addition, the framework is modular, so developers can include only those components they need. This modularity helps optimize application performance and reduce application footprint.
  6. Configuration System:  The ASP.NET Core configuration system supports a variety of configuration sources, including environment variables, JSON files, and command-line arguments.
  7. Built-in Middleware:  In ASP.NET Core, middleware components are used to handle requests and responses. Developers can add or remove middleware components as needed.
  8. Modern Development Practices:  With the framework, you can integrate single-page applications (SPA) as well as asynchronous programming, RESTful APIs, and asynchronous programming.
  9. Security: Data protection, authentication, and authorization mechanisms are included with ASP.NET Core to secure web applications.

Advantages of ASP.NET Core

  1. High Performance Performance optimized for modern workloads: ASP.NET Core's efficient runtime and reduced memory overhead contribute to faster response times and less resource consumption.
  2. Cross-Platform Deployment:  ASP.NET Core applications can be built and deployed on a variety of operating systems, making it easier to reach different environments.
  3. Flexibility and Extensibility:  ASP.NET Core's modular nature allows for flexible configurations and the ability to extend functionality through custom middleware and libraries.
  4. Improved Development Experience:  ASP.NET Core supports a wide variety of development tools and environments, including Visual Studio, Visual Studio Code, and command-line interfaces, enhancing developer productivity.
  5. Community and Ecosystem:  ASP.NET Core has a strong community and a rich ecosystem of libraries and tools, which provide developers with extensive support and resources.

Getting Started with ASP.NET Core: A Practical Example

In order to demonstrate ASP.NET Core's capabilities, let's create a simple web application using .NET 8 and C# 12. This API allows CRUD (Create, Read, Update, Delete) operations to manage books.

Step 1: Setting Up the Project

  1. Install .NET 8 SDK: Make sure you have the .NET 8 SDK installed on your computer. You can download it from the .NET website.
  2. Create a New ASP.NET Core Project:  To create a new ASP.NET Core Web API project, open a terminal or command prompt and run the following command:

dotnet new webapi -n BookStoreDemo

Navigate to the project directory:

cd BookStoreDemo

Step 2: Following DRY and KISS we are using GlobalUsing.cs class

To take advantage of the global using we need to create a new C# Class in the root of the project name GlobalUsing.cs and we will need to install a few NuGet Packages, which we require for this demo example. We need to install the following two NuGet Packages

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.InMemory

And then we copy the following code from below.

// GlobalUsing.cs
global using BookStore.Data;
global using BookStoreApi.Models;
global using Microsoft.AspNetCore.Mvc;
global using Microsoft.EntityFrameworkCore;

Step 3: Define the Book Model

Our book entity's data structure will be represented by a Book model class in the Models folder using record.

// Models/Book.cs
 using System.ComponentModel.DataAnnotations;
namespace BookStoreApi.Models;
public record Book(
    int Id,
    [property: Required]
    [property: StringLength(100)]
    string Title,
    [property: Required]
    [property: StringLength(100)]
    string Author,
    DateTime PublishedDate
);

Step 4: Create a Data Context

Use Entity Framework Core to manage the book data. Create a BookContext class in the Data folder.

// Data/BookContext.cs
namespace BookStore.Data;

public class BookContext : DbContext
{
    public BookContext(DbContextOptions<BookContext> options) : base(options) { }

    public DbSet<Book> Books { get; set; }
}

Step 5: Configure Services

Ensure that Program.cs registers the BookContext and configures dependency injection.

// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<BookContext>(options =>
    options.UseInMemoryDatabase("BookStoreDb"));

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Step 6: Create the Books Controller

Create a BooksController under Controllers to handle API requests.

// Controllers/BooksController.cs
 namespace BookStoreApi.Controllers;

[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
    private readonly BookContext _context;

    public BooksController(BookContext context)
    {
        _context = context;
    }

    // GET: api/Books
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Book>>> GetBooks()
    {
        return await _context.Books.ToListAsync();
    }

    // GET: api/Books/5
    [HttpGet("{id}")]
    public async Task<ActionResult<Book>> GetBook(int id)
    {
        var book = await _context.Books.FindAsync(id);

        if (book == null)
        {
            return NotFound();
        }

        return book;
    }

    // POST: api/Books
    [HttpPost]
    public async Task<ActionResult<Book>> PostBook(Book book)
    {
        _context.Books.Add(book);
        await _context.SaveChangesAsync();

        return CreatedAtAction(nameof(GetBook), new { id = book.Id }, book);
    }

    // PUT: api/Books/5
    [HttpPut("{id}")]
    public async Task<IActionResult> PutBook(int id, Book book)
    {
        if (id != book.Id)
        {
            return BadRequest();
        }

        _context.Entry(book).State = EntityState.Modified;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!BookExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return NoContent();
    }

    // DELETE: api/Books/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteBook(int id)
    {
        var book = await _context.Books.FindAsync(id);
        if (book == null)
        {
            return NotFound();
        }

        _context.Books.Remove(book);
        await _context.SaveChangesAsync();

        return NoContent();
    }

    private bool BookExists(int id)
    {
        return _context.Books.Any(e => e.Id == id);
    }
}

Step 7: Creating the BookStoreApi.http file

As a convenience, the BookStoreApi.http file can be used to test and interact with ASP.NET Core API endpoints defined in the BooksController. Each HTTP request is clearly marked and structured to facilitate easy testing, and it includes examples of CRUD (Create, Read, Update, Delete) operations for the Books resource. As an example, a GET request retrieves all books or a specific one by ID, while a POST request creates a new book based on a specified JSON payload. An existing book can be updated using the PUT request, and a book can be deleted by its ID with the DELETE request. The BookStoreApi.http file can be used with tools such as Visual Studio Code's REST Client extension to test API endpoints, validate functionality, and ensure robust data operations for applications.

### Get all books
GET http://localhost:5082/api/books
Accept: application/json

###

### Get a single book by id
GET http://localhost:5082/api/books/1
Accept: application/json

###

### Create a new book
POST http://localhost:5082/api/books
Content-Type: application/json

{
    "title": "New Book Title",
    "author": "Author Name",
    "publishedDate": "2024-08-18T00:00:00Z"
}

###

### Update an existing book
PUT http://localhost:5082/api/books/1
Content-Type: application/json

{
    "id": 1,
    "title": "Updated Book Title",
    "author": "Updated Author Name",
    "publishedDate": "2024-08-18T00:00:00Z"
}

###

### Delete a book by id
DELETE http://localhost:5082/api/books/1
Accept: application/json

Step 8: Run and Test the Application

  1. Run the Application: Using the following command, you can start the application:

dotnet run

  1. Test the API: Test the API endpoints with a tool like Postman or curl:
  • GET /api/Books –  The list of books can be retrieved.
  • GET /api/Books/{id} –  By ID, retrieve a specific book.
  • POST /api/Books – Add a new book.
  • PUT /api/Books/{id} – Update an existing book.
  • DELETE /api/Books/{id} – Delete a book.

Summary

 A robust and versatile framework, ASP.NET Core is a great choice for building modern web applications. It provides a solid foundation for creating scalable and maintainable applications due to its cross-platform capabilities, high performance, and comprehensive feature set. Developers can create powerful web solutions that meet contemporary expectations and requirements by leveraging ASP.NET Core's features and following best practices.

Check out my GitHub repository for the source code of this article. If you enjoyed this article, please follow me on LinkedIn https://www.linkedin.com/in/ziggyrafiq/ and like it. Thank you for your support.


Capgemini
Capgemini is a global leader in consulting, technology services, and digital transformation.