React + ASP.NET Core CRUD Tutorial

This tutorial guides you through creating a full-stack application using React.js (frontend) and ASP.NET Core WebAPI (backend). React handles the UI and sends HTTP requests to the WebAPI for data manipulation.

Backend: ASP.NET Core Web API

Step 1: Create the WebAPI Project

dotnet new webapi -n ProductApi
cd ProductApi

Step 2: Add Database Configuration

"ConnectionStrings": {
  "DefaultConnection": "Server=YOUR_SERVER;Database=ProductDb;Trusted_Connection=True;"
}

Step 3: Install EF Core Packages

dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools

Step 4: Create the Product Model

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Step 5: Create DbContext

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
    public DbSet<Product> Products { get; set; }
}

Step 6: Register DbContext in Program.cs

builder.Services.AddDbContext<AppDbContext>(
    options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll",
        builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
app.UseCors("AllowAll");

Step 7: Create ProductsController

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly AppDbContext _context;
    public ProductsController(AppDbContext context) => _context = context;

    [HttpGet]
    public async Task<IEnumerable<Product>> Get() => await _context.Products.ToListAsync();

    [HttpPost]
    public async Task<ActionResult<Product>> Post(Product product)
    {
        _context.Products.Add(product);
        await _context.SaveChangesAsync();
        return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
    }

    [HttpPut("{id}")]
    public async Task<IActionResult> Put(int id, Product product)
    {
        if (id != product.Id) return BadRequest();
        _context.Entry(product).State = EntityState.Modified;
        await _context.SaveChangesAsync();
        return NoContent();
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> Delete(int id)
    {
        var product = await _context.Products.FindAsync(id);
        if (product is null) return NotFound();
        _context.Products.Remove(product);
        await _context.SaveChangesAsync();
        return NoContent();
    }
}

Step 8: Apply Migrations

dotnet ef migrations add InitialCreate
dotnet ef database update

Frontend: React App (Created with CRA)

Step 1: Create React App

npx create-react-app product-client
cd product-client

Step 2: Install Axios

npm install axios

Step 3: Create ProductComponent.js


            import React, { useEffect, useState } from 'react';
import axios from 'axios';

const API_URL = "https://localhost:5001/api/products";

function ProductComponent() {
  const [products, setProducts] = useState([]);
  const [form, setForm] = useState({ id: 0, name: "", price: "" });
  const [isEditing, setIsEditing] = useState(false);

  useEffect(() => {
    fetchProducts();
  }, []);

  const fetchProducts = () => {
    axios.get(API_URL)
      .then(res => setProducts(res.data))
      .catch(err => console.error("Error fetching products:", err));
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setForm(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    if (isEditing) {
      // Update product
      axios.put(`${API_URL}/${form.id}`, form)
        .then(() => {
          setForm({ id: 0, name: "", price: "" });
          setIsEditing(false);
          fetchProducts();
        });
    } else {
      // Create new product
      axios.post(API_URL, form)
        .then(() => {
          setForm({ id: 0, name: "", price: "" });
          fetchProducts();
        });
    }
  };

  const handleEdit = (product) => {
    setForm(product);
    setIsEditing(true);
  };

  const handleDelete = (id) => {
    axios.delete(`${API_URL}/${id}`)
      .then(fetchProducts)
      .catch(err => console.error("Error deleting product:", err));
  };

  const cancelEdit = () => {
    setForm({ id: 0, name: "", price: "" });
    setIsEditing(false);
  };

  return (
        

{isEditing ? "Edit Product" : "Add Product"}

{isEditing && }

Product List

    {products.map(p => (
  • {p.name} - ${p.price}
  • ))}
); } export default ProductComponent;

Step 4: Use Component in App.js

import React from 'react';
import ProductComponent from './ProductComponent';

function App() {
  return (
    <div>
      <ProductComponent />
    </div>
  );
}

export default App;

Summary

You now have a React frontend and an ASP.NET Core backend working independently. React handles UI rendering and sends CRUD requests to the WebAPI. The API processes requests and responds with JSON data, which React displays dynamically.