Contents

0. Project Structure 1. Database / Models 2. Controllers → JSON API 3. JavaScript API 4. Razor View 5. Testing 6. Complete Data Flow

Back

Fullstack .NET Example - Burger Shop

From Database to Frontend with JS and Razor Views (ASP.NET Core)

0️⃣ Project Structure → Files & Folders

BurgerShop/                    // Solution / project root
│
├── BurgerShop/                // ASP.NET Core web project
│   ├── Controllers/          // Controllers (API & MVC)
│   ├── Models/               // C# models (Burger, CartItem)
│   ├── Views/                // Razor views (.cshtml)
│   │   └── Home/
│   │       └── Index.cshtml
│   ├── wwwroot/             // static files: css, js, images
│   ├── Program.cs            // Host & configure
│   └── Startup.cs            // Middleware, endpoints (if present)
│
├── tests/                    // xUnit / integration tests
├── appsettings.json           // DB connection
└── BurgerShop.sln             // Solution file
      

Use EF Core migrations to keep the DB schema in sync (or configure PostgreSQL / SQL Server in appsettings.json).

1️⃣ Database → Models (C# / EF Core)

Define the Burger entity (EF Core):

// Models/Burger.cs
using System.ComponentModel.DataAnnotations;

namespace BurgerShop.Models
{
    public class Burger
    {
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public decimal Price { get; set; }

        public object ToDto() => new { "id" = Id, "name" = Name, "price" = Price };
    }
}
      

Use EF Core DbContext to map models to your PostgreSQL (or other) database.

2️⃣ Controllers → JSON API (ASP.NET Core)

Example API controller returning burgers as JSON (attribute routing):

// Controllers/BurgersController.cs
using Microsoft.AspNetCore.Mvc;
using BurgerShop.Models;

namespace BurgerShop.Controllers
{
    [ApiController]
    [Route]("api/[controller]")
    public class BurgersController : ControllerBase
    {
        private readonly AppDbContext _context;

        public BurgersController(AppDbContext context) {
            _context = context;
        }

        [HttpGet]
        public async Task<IActionResult> GetAll() {
            var burgers = await _context.Burgers.ToListAsync();
            return Ok(burgers.Select(b => b.ToDto()));
        }
    }
}
      

Alternatively, register MVC endpoints in Program.cs or Startup.cs (MapControllers / UseEndpoints).

// Program.cs (minimal example)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AppDbContext>(options => /* configure provider */);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
      

3️⃣ JavaScript → API Consumption

Client-side function to post cart items to the .NET API:

async function addToCart(burgerId, qty = 1) {
  const res = await fetch('/api/cart', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ burgerId, quantity: qty })
  });
  return res.json();
}
      

This JS fetch hits an ASP.NET Core controller action that processes the cart (create/update/delete).

4️⃣ Razor View → Initial Render

Example Razor (.cshtml) to render burgers server-side and provide buttons for JS:

@model IEnumerable<BurgerShop.Models.Burger>

<ul id="catalog">
  @foreach (var b in Model) {
    <li>
      <strong>@b.Name</strong> — $@b.Price
      <button class="add-to-cart" data-id=@b.Id>Add</button>
    </li>
  }
</ul>
      

Razor binds C# model properties into the HTML and the same JS handlers work to call the API.

5️⃣ Testing → .NET (xUnit) & JS

Examples: unit test for model / controller and a JS test snippet.

// tests/ModelTests.cs (xUnit)
using Xunit;
using BurgerShop.Models;

public class ModelTests
{
    [Fact]
    public void Burger_ToDto_Works()
    {
        var b = new Burger { Name = "Cheese", Price = 5.99m };
        var dto = b.ToDto();
        Assert.Equal("Cheese", ((dynamic)dto).name);
    }
}

// JS test (simple console / ad-hoc)
async function testAddToCart() {
  const res = await addToCart(1, 2);
  console.log('Cart response:', res);
}
      

For integration tests use WebApplicationFactory and EF Core InMemory provider or testcontainers for DB.

6️⃣ Complete Data Flow

Layer Example Purpose
Database EF Core migrations Schema + seed data
C# Models Burger class Map DB rows to C# objects
Controllers /api/burgers → BurgersController.GetAll() Return JSON, handle cart mutations
Frontend JS fetch('/api/cart') Send/receive JSON; dynamic UI
Razor Views Index.cshtml Server-render initial page and data
Testing xUnit + JS console tests Unit + integration tests