.NET  

Integrating React with ASP.NET Core 8 in Visual Studio 2022

Merging React (for highly interactive UIs) with ASP.NET Core (for robust, enterprise-grade backends) provides.

  • Real-world separation of concerns (frontend/backend)
  • Strong performance and security from .NET
  • Enhanced developer productivity with Visual Studio’s tooling

Solution Structure in Visual Studio 2022

ReactDotNetApp (Solution)
├── ReactDotNetApp.Server       ← ASP.NET Core 8 Web API
│   ├── Controllers/
│   ├── Program.cs
│   ├── appsettings.json
│   └── launchSettings.json
└── ReactDotNetApp.ClientApp    ← React + Vite frontend
    ├── src/
    │   ├── App.jsx
    │   └── api.js
    ├── vite.config.js
    ├── package.json
    └── public/

This structure allows seamless coordination and deployment between the frontend and backend.

1. Create the .NET 8 Web API Project

Steps

  • Open Visual Studio 2022.
  • Select the ASP.NET Core Web API project template.
  • Name it: ReactDotNetApp.Server
  • Target .NET 8, enable.
    • Use controllers (no minimal API for now)
    • Enable OpenAPI (Swagger)
    • Uncheck the authentication for simplicity
  • ASP.NET Core Web API is ideal for backend services that provide JSON-based REST endpoints.
  • You'll interact with these endpoints from React using HTTP requests (fetch, axios, etc.).

Sample Controller

Controllers/TodoController.cs

using Microsoft.AspNetCore.Mvc;
namespace ReactDotNetApp.Server.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TodoController : ControllerBase
    {
        private static readonly List<string> Todos = new()
        {
            "Learn React",
            "Integrate with .NET",
            "Deploy Fullstack App"
        };
        [HttpGet]
        public IActionResult GetTodos() => Ok(Todos);
    }
}

2. Add React Frontend (ClientApp)

Steps

  • Right-click the solution → Add → New Project
  • Select React + ASP.NET Core template (built-in)
    • Name: ReactDotNetApp.ClientApp
  • Confirm that it uses Vite, not CRA

Note. Make sure you have Node.js (18+) and npm installed!

The React app is structured using Vite, which is a fast build tool that improves dev experience through HMR (Hot Module Replacement) and simpler configuration.

3. Enable CORS in .NET Backend

Program.cs

var builder = WebApplication.CreateBuilder(args);
// Configure CORS
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowReactApp", policy =>
    {
        policy.WithOrigins("http://localhost:5173")
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});
// Add services to the container
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Enable CORS
app.UseCors("AllowReactApp");

// Configure the HTTP request pipeline
app.UseAuthorization();
app.MapControllers();
app.Run();

CORS (Cross-Origin Resource Sharing) is required to allow the frontend (running on localhost:5173) to communicate with the backend (on localhost:5001 or similar).

4. Configure React’s Vite Proxy

vite.config.js

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
  plugins: [react()],
  server: {
    proxy: {
      '/api': 'https://localhost:5001', // match your backend port
    }
  }
});

This proxy redirects requests like /api/todo from React to the backend server without CORS errors. It simplifies fetch calls in development.

5. Connect React to .NET API

src/api.js

export const fetchTodos = async () => {
  const response = await fetch('/api/todo');
  if (!response.ok) {
    throw new Error("API call failed");
  }
  return await response.json();
};

src/App.jsx

import { useEffect, useState } from 'react';
import { fetchTodos } from './api';

export default function App() {
  const [todos, setTodos] = useState([]);
  useEffect(() => {
    fetchTodos()
      .then(setTodos)
      .catch(console.error);
  }, []);
  return (
    <div>
      <h1>Todo List from .NET API</h1>
      <ul>
        {todos.map((todo, idx) => (
          <li key={idx}>{todo}</li>
        ))}
      </ul>
    </div>
  );
}

React’s useEffect runs after the component mounts and is ideal for calling APIs. We use useState to store the API data.

6. Run Both Projects Together

Steps

  • Right-click on the solution → Set Startup Projects
  • Choose Multiple startup projects
  • Set both ReactDotNetApp.Server and ReactDotNetApp.ClientApp to Start
  • Press F5

This launches

  • .NET Web API at https://localhost:5001
  • React (Vite) at http://localhost:5173

You’ll see the todo list fetched from the backend displayed in the browser.

Final Preview

You should see your full-stack app working locally.

  • React frontend at /
  • API calls fetched from backend /api/todo
  • Everything is bundled inside Visual Studio 2022

Conclusion

This setup combines the flexibility of React with the robustness of .NET 8 Web API, all running seamlessly together in Visual Studio 2022.

Key Takeaways

  • Vite simplifies React builds and HMR.
  • ASP.NET Core is perfect for API-first architecture.
  • Visual Studio makes full-stack development smoother with integrated tooling.