Entity Framework with MongoDB in a .NET Core Web API with React UI
When building modern web applications, integrating a robust backend with a user-friendly frontend is a common challenge. Combining MongoDB, Entity Framework (EF), and a .NET Core Web API with a React UI can provide a scalable and efficient solution. This blog walks you through implementing this stack using the code-first approach and migrations.

Prerequisites
Before diving in, ensure you have the following installed:
- .NET SDK (6.0 or later recommended)
- Node.js (for React)
- MongoDB (local or cloud-based)
- Visual Studio Code or another preferred IDE
Step 1: Setting Up the .NET Core Web API
Create a New .NET Core Web API Project
Run the following command to scaffold a new project:
mkdir MongoEFReactApp
cd MongoEFReactApp
dotnet new webapi -n MongoEFWebAPI
Add Required Packages
Install the necessary NuGet packages:
cd MongoEFWebAPI
dotnet add package Microsoft.EntityFrameworkCore
For MongoDB integration:
dotnet add package MongoDB.Driver
Configure MongoDB Connection
In the appsettings.json
file, add your MongoDB connection string:
{
"ConnectionStrings": {
"MongoDB": "mongodb://localhost:27017/ProductsDatabase"
}
}
Step 2: Creating the Data Model
Define Your Entity Class
Create a new folder Models
and add a class Product
:
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
namespace MongoEFWebAPI.Models
{
public class Product
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; } // MongoDB uses string for Id
public string Name { get; set; }
public double Price { get; set; }
public int Quantity { get; set; }
}
}
Implement the Database Context
Create a new folder Data
and add a MongoDbContext
class:
using MongoDB.Driver;
using MongoEFWebAPI.Models;
namespace MongoEFWebAPI.Data
{
public class MongoDbContext
{
private readonly IMongoDatabase _database;
public MongoDbContext(IConfiguration configuration)
{
var client = new MongoClient(configuration.GetConnectionString("MongoDB"));
_database = client.GetDatabase("ProductsDatabase");
}
public IMongoCollection<Product> Products => _database.GetCollection<Product>("Products");
}
}
Step 3: Setting Up the Repository Pattern
Create a new folder Repositories
and add an interface IProductRepository
:
using MongoEFWebAPI.Models;
namespace MongoEFWebAPI.Repositories
{
public interface IProductRepository
{
Task<IEnumerable<Product>> GetAllProductsAsync();
Task<Product> GetProductByIdAsync(string id);
Task AddProductAsync(Product product);
Task UpdateProductAsync(Product product);
Task DeleteProductAsync(string id);
}
}
Then, implement the repository:
using MongoDB.Driver;
using MongoEFWebAPI.Models;
using MongoEFWebAPI.Data;
namespace MongoEFWebAPI.Repositories
{
public class ProductRepository : IProductRepository
{
private readonly MongoDbContext _context;
public ProductRepository(MongoDbContext context)
{
_context = context;
}
public async Task<IEnumerable<Product>> GetAllProductsAsync()
{
return await _context.Products.Find(_ => true).ToListAsync();
}
public async Task<Product> GetProductByIdAsync(string id)
{
return await _context.Products.Find(p => p.Id == id).FirstOrDefaultAsync();
}
public async Task AddProductAsync(Product product)
{
await _context.Products.InsertOneAsync(product);
}
public async Task UpdateProductAsync(Product product)
{
await _context.Products.ReplaceOneAsync(p => p.Id == product.Id, product);
}
public async Task DeleteProductAsync(string id)
{
await _context.Products.DeleteOneAsync(p => p.Id == id);
}
}
}
Step 4: Creating the Controller
Create a ProductsController
in the Controllers
folder:
using Microsoft.AspNetCore.Mvc;
using MongoEFWebAPI.Models;
using MongoEFWebAPI.Repositories;
namespace MongoEFWebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
private readonly IProductRepository _repository;
public ProductsController(IProductRepository repository)
{
_repository = repository;
}
[HttpGet]
public async Task<IActionResult> GetAll()
{
var products = await _repository.GetAllProductsAsync();
return Ok(products);
}
[HttpGet("{id}")]
public async Task<IActionResult> GetById(string id)
{
var product = await _repository.GetProductByIdAsync(id);
if (product == null) return NotFound();
return Ok(product);
}
[HttpPost]
public async Task<IActionResult> Create([FromBody] Product product)
{
await _repository.AddProductAsync(product);
return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}
[HttpPut("{id}")]
public async Task<IActionResult> Update(string id, [FromBody] Product product)
{
if (id != product.Id) return BadRequest();
await _repository.UpdateProductAsync(product);
return NoContent();
}
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(string id)
{
await _repository.DeleteProductAsync(id);
return NoContent();
}
}
}
And finally adjust the Program.cs as follow
using MongoEFWebAPI.Repositories;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IProductRepository, ProductRepository>();
builder.Services.AddScoped<MongoEFWebAPI.Data.MongoDbContext>();
builder.Services.AddCors();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:3000"));
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Step 5: Integrating with a React UI
Set Up the React App
Navigate to the root folder and create a React app:
npx create-react-app react-ui
cd react-ui
Fetch API Data
In the src
folder, create a services
directory with a productService.js
file:
const API_URL = "http://localhost:5000/api/products";
export const fetchProducts = async () => {
const response = await fetch(API_URL);
return response.json();
};
Display Products
Update App.js
to display the product data:
import React, { useEffect, useState } from "react";
import { fetchProducts } from "./services/productService";
function App() {
const [products, setProducts] = useState([]);
useEffect(() => {
fetchProducts().then(setProducts);
}, []);
return (
<div>
<h1>Product List</h1>
<ul>
{products.map((product) => (
<li key={product.id}>
{product.name} - ${product.price}
</li>
))}
</ul>
</div>
);
}
export default App;
The comple source code is available at https://gitlab.com/mvineetsharma/microsoft/DotNetCoreEntetyFrameworkMongorepositoryPatternCodeFirstCodeAPI
The API project also contain the ProductsCollection.json for sample data in MongoDB
Conclusion
By following this tutorial, you’ve built a full-stack application integrating MongoDB with Entity Framework, a .NET Core Web API, and a React UI. This approach leverages the flexibility of MongoDB and the power of .NET Core, creating a modern and scalable architecture.