Introduction
Welcome to our comprehensive guide on building a React.js application that interacts with a .NET Core 8 Web API! This tutorial will walk you through creating a backend API for managing a list of books and a frontend application to consume this API. Whether you’re a seasoned developer or just starting, you’ll find valuable insights and practical steps to enhance your skills.
What You’ll Learn
- Setting up a .NET Core 8 Web API
- Implementing CRUD operations
- Enabling CORS for cross-origin requests
- Creating a React.js frontend to interact with the API
Prerequisites
- Node.js and npm installed – for React.js application development.
- Visual Studio 2022 or Visual Studio Code – for .NET Core Web API development.
- .NET Core 8 SDK – to develop and run the API.
Step 1: Setting Up the .NET Core 8 Web API
1. Create a New Web API Project:
- Open Visual Studio.
- Click on “Create a new project”.
- Select “ASP.NET Core Web API” and click “Next”.
- Name your project and click “Create”.
- Choose “.NET 8.0” as the target framework and click “Create”.
2. Define the Book Model:
Open the Models
folder (create this folder if it doesn’t exist) and add a new class Book.cs
.
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Genre { get; set; }
public int Year { get; set; }
}
3. Create the Book Controller:
Open the Controllers
folder and add a new BooksController.cs
.
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
private static readonly List<Book> Books = new List<Book>
{
new Book { Id = 1, Title = "1984", Author = "George Orwell", Genre = "Dystopian", Year = 1949 },
new Book { Id = 2, Title = "To Kill a Mockingbird", Author = "Harper Lee", Genre = "Fiction", Year = 1960 }
};
[HttpGet]
public ActionResult<IEnumerable<Book>> GetBooks()
{
return Ok(Books);
}
[HttpGet("{id}")]
public ActionResult<Book> GetBook(int id)
{
var book = Books.FirstOrDefault(b => b.Id == id);
if (book == null)
{
return NotFound();
}
return Ok(book);
}
[HttpPost]
public ActionResult<Book> CreateBook(Book book)
{
book.Id = Books.Count + 1;
Books.Add(book);
return CreatedAtAction(nameof(GetBook), new { id = book.Id }, book);
}
[HttpPut("{id}")]
public IActionResult UpdateBook(int id, Book updatedBook)
{
var book = Books.FirstOrDefault(b => b.Id == id);
if (book == null)
{
return NotFound();
}
book.Title = updatedBook.Title;
book.Author = updatedBook.Author;
book.Genre = updatedBook.Genre;
book.Year = updatedBook.Year;
return NoContent();
}
[HttpDelete("{id}")]
public IActionResult DeleteBook(int id)
{
var book = Books.FirstOrDefault(b => b.Id == id);
if (book == null)
{
return NotFound();
}
Books.Remove(book);
return NoContent();
}
}
4. Run the API:
- Press
F5
to run the API. - Ensure the API is working by navigating to
https://localhost:{port}/api/books
.
Step 2: Setting Up the React.js Application
1. Create a New React Application:
Open a terminal and run the following command:
npx create-react-app book-management-app
cd book-management-app
2. Install Axios for HTTP Requests:
In the terminal, install Axios:
npm install axios
3. Create a Service for API Calls:
In the src
folder, create a new folder services
and a file BookService.js
.
import axios from 'axios';
const API_URL = 'https://localhost:{port}/api/books';
export const getBooks = async () => {
try {
const response = await axios.get(API_URL);
return response.data;
} catch (error) {
console.error('Error fetching books:', error);
throw error;
}
};
export const getBook = async (id) => {
try {
const response = await axios.get(`${API_URL}/${id}`);
return response.data;
} catch (error) {
console.error(`Error fetching book with id ${id}:`, error);
throw error;
}
};
export const createBook = async (book) => {
try {
const response = await axios.post(API_URL, book);
return response.data;
} catch (error) {
console.error('Error creating book:', error);
throw error;
}
};
export const updateBook = async (id, book) => {
try {
const response = await axios.put(`${API_URL}/${id}`, book);
return response.data;
} catch (error) {
console.error(`Error updating book with id ${id}:`, error);
throw error;
}
};
export const deleteBook = async (id) => {
try {
const response = await axios.delete(`${API_URL}/${id}`);
return response.data;
} catch (error) {
console.error(`Error deleting book with id ${id}:`, error);
throw error;
}
};
4. Create a Book Management Component:
In the src
folder, create a new folder components
and a file BookManagement.js
.
import React, { useEffect, useState } from 'react';
import { getBooks, createBook, updateBook, deleteBook } from '../services/BookService';
const BookManagement = () => {
const [books, setBooks] = useState([]);
const [newBook, setNewBook] = useState({ title: '', author: '', genre: '', year: '' });
useEffect(() => {
const fetchData = async () => {
try {
const data = await getBooks();
setBooks(data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchData();
}, []);
const handleInputChange = (e) => {
const { name, value } = e.target;
setNewBook({ ...newBook, [name]: value });
};
const handleAddBook = async () => {
try {
const book = await createBook(newBook);
setBooks([...books, book]);
setNewBook({ title: '', author: '', genre: '', year: '' });
} catch (error) {
console.error('Error adding book:', error);
}
};
const handleDeleteBook = async (id) => {
try {
await deleteBook(id);
setBooks(books.filter((book) => book.id !== id));
} catch (error) {
console.error('Error deleting book:', error);
}
};
return (
<div>
<h1>Book Management</h1>
<div>
<input
type="text"
name="title"
placeholder="Title"
value={newBook.title}
onChange={handleInputChange}
/>
<input
type="text"
name="author"
placeholder="Author"
value={newBook.author}
onChange={handleInputChange}
/>
<input
type="text"
name="genre"
placeholder="Genre"
value={newBook.genre}
onChange={handleInputChange}
/>
<input
type="number"
name="year"
placeholder="Year"
value={newBook.year}
onChange={handleInputChange}
/>
<button onClick={handleAddBook}>Add Book</button>
</div>
<ul>
{books.map((book) => (
<li key={book.id}>
{book.title} by {book.author} ({book.year})
<button onClick={() => handleDeleteBook(book.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
};
export default BookManagement;
5. Use the Book Management Component in App.js:
Replace the contents of src/App.js
with the following:
import React from 'react';
import './App.css';
import BookManagement from './components/BookManagement';
function App() {
return (
<div className="App">
<header className="App-header">
<BookManagement />
</header>
</div>
);
}
export default App;
6. Run the React Application:
In the terminal, run the following command:
npm start
Open your browser and navigate to http://localhost:3000
to see the book management interface.
3. To allow your React.js application to interact with your .NET Core 8 Web API, you need to enable CORS (Cross-Origin Resource Sharing) in your Web API. Here’s how to do it:
Run the following command to install the CORS package:
Install-Package Microsoft.AspNetCore.Cors
Configure CORS in Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Add CORS services and policy
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll",
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Use the CORS policy
app.UseCors("AllowAll");
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
4. Run the API:
Press F5
to run the API.
Ensure the API is working by navigating to https://localhost:{port}/api/books
.
Congratulations! You’ve successfully built a React.js application that consumes a .NET Core 8 Web API. We covered setting up the backend API, enabling CORS, and creating a frontend application to interact with the API.
Have questions or suggestions? Drop a comment below!
Thank you for following along! We hope you found this tutorial helpful. Happy coding!