ASP.NET Core Complete Tutorial (ShopNest)
Lesson 3 of 75 4% of course

ASP.NET Core Project Structure Explained

1 · 8 min · 5/24/2026

Learn ASP.NET Core Project Structure Explained in our free ASP.NET Core Complete Tutorial (ShopNest) series. Step-by-step explanations, examples, and interview tips on Toolliyo Academy.

Sign in to track progress and bookmarks.

ASP.NET Core project structure — ShopNest
Article 3 of 75 · Module 1: Foundations · ShopNest solution layout
Target keyword: asp.net core project structure · Read time: ~24 min · .NET: 8 / 9 · Project: ShopNest E-Commerce Startup

Introduction

When you run dotnet new, Visual Studio or the CLI generates a folder full of files — and most beginners ignore half of them until a production bug forces a crash course. Understanding ASP.NET Core project structure is how you stop feeling lost on day one at an e-commerce startup (or a TCS bench project) and start navigating like a professional.

In this lesson we dissect every important file in a new project, compare MVC vs Web API layouts, and show how ShopNest — our 75-article e-commerce tutorial — organizes code across ShopNest.Web, ShopNest.API, and supporting class libraries.

After this article you will

  • Explain the purpose of Program.cs, appsettings, wwwroot, and the .csproj file
  • Configure launch profiles and local HTTPS ports confidently
  • Compare MVC, Web API, and Razor Pages project layouts
  • Sketch a production folder structure for an e-commerce app
  • Answer fresher interview questions about project files

Prerequisites

Concept deep-dive

Level 1 — Analogy

Think of an ASP.NET Core project as a restaurant floor plan. Program.cs is the manager who opens the restaurant and assigns staff roles. Controllers are waiters taking orders. Views are the plates presented to customers. wwwroot is the décor and menu cards (static assets). appsettings.json is the recipe binder with house rules — different binders for lunch rush (Development) vs dinner service (Production).

Level 2 — Minimal hosting model

Since .NET 6, ASP.NET Core uses a minimal hosting model: one Program.cs replaces the old Program.cs + Startup.cs pair. Everything — service registration (DI) and middleware pipeline — lives in one file unless you split it for Clean Architecture (Article 44).

Level 3 — ShopNest multi-project layout

ShopNest/                          ← solution folder
├── ShopNest.sln
├── ShopNest.Web/                  ← MVC storefront (customer UI)
├── ShopNest.API/                  ← REST API (mobile app backend)
├── ShopNest.Admin/                ← Razor Pages admin (later articles)
├── src/
│   ├── ShopNest.Domain/           ← entities (Product, Order)
│   ├── ShopNest.Application/      ← services, DTOs (Article 44+)
│   └── ShopNest.Infrastructure/   ← EF Core, email (Article 44+)
└── tests/
    └── ShopNest.Tests/            ← xUnit (Article 54+)

Common misconceptions

❌ MYTH: Startup.cs still exists in .NET 8 templates.
✅ TRUTH: New templates use top-level statements in Program.cs; Startup is legacy for older migrations.

❌ MYTH: Put business logic in Controllers for speed.
✅ TRUTH: Controllers should be thin; services hold rules — interviewers at Infosys and product firms both flag fat controllers.

❌ MYTH: appsettings.json is safe to commit with real passwords.
✅ TRUTH: Use User Secrets locally and Azure Key Vault in production (Article 64).

Every file and folder explained

Create a reference project: dotnet new webapp -n ShopNest.Web -o ShopNest.Web

PathPurpose
Program.csApplication entry — builds host, registers services, configures middleware, runs app
ShopNest.Web.csprojProject manifest — target framework (net8.0), NuGet packages, build options
appsettings.jsonDefault configuration (logging levels, allowed hosts, connection strings placeholder)
appsettings.Development.jsonOverrides for Development environment — detailed errors, local SQL connection
Properties/launchSettings.jsonLocal launch profiles — URLs, ports, environment variable ASPNETCORE_ENVIRONMENT
wwwroot/Static files served directly — CSS, JS, images, favicon (UseStaticFiles)
Pages/ (Razor Pages)Page-centric UI — .cshtml + .cshtml.cs code-behind
Controllers/ + Views/ (MVC)Controller actions return Views; convention-based routing
Models/ViewModels and domain types used by UI layer
bin/, obj/Build output — never commit; listed in .gitignore

Program.cs deep dive

// File: ShopNest.Web/Program.cs
var builder = WebApplication.CreateBuilder(args);

// ── Service registration (DI container) ──
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews(); // if MVC
builder.Services.AddDbContext<ShopNestDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

var app = builder.Build();

// ── Middleware pipeline (ORDER MATTERS) ──
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();       // wwwroot
app.UseRouting();
app.UseAuthentication();    // later articles
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();       // MVC + API endpoints

app.Run();

Top-level statements hide the Main method — the compiler generates it. This reduces boilerplate for learning and production alike.

appsettings.json vs Development

// appsettings.json — shared defaults
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": ""
  }
}
// appsettings.Development.json — local only
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft.EntityFrameworkCore": "Information"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost\\SQLEXPRESS;Database=ShopNestDb;Trusted_Connection=True;TrustServerCertificate=True;"
  }
}

Configuration merges later files over earlier ones; environment-specific file loads when ASPNETCORE_ENVIRONMENT=Development.

launchSettings.json

{
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "applicationUrl": "http://localhost:5280",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "https": {
      "commandName": "Project",
      "applicationUrl": "https://localhost:7280;http://localhost:5280",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Visual Studio's green ▶ button uses the https profile by default. IIS Express profile appears when the web workload is installed.

.csproj essentials

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.*" />
  </ItemGroup>
</Project>

Sdk="Microsoft.NET.Sdk.Web" pulls in ASP.NET Core defaults. Add packages with dotnet add package PackageName.

wwwroot and static files

wwwroot/
├── css/site.css
├── js/site.js
├── lib/           ← LibMan / npm client libraries
└── images/logo.png

Files here are served at root URL: /css/site.css. Use asp-append-version="true" on script tags for cache busting (Article 12).

MVC vs Web API project structure

AspectMVC (ShopNest.Web)Web API (ShopNest.API)
Templatedotnet new mvcdotnet new webapi
Primary outputHTML (Razor views)JSON/XML
Key foldersControllers, Views, Models, wwwrootControllers, sometimes DTOs folder
RoutingConventional + viewsAttribute routes /api/products
Typical useStorefront, admin UIMobile app, SPA backend

ShopNest uses both: Web for SEO-friendly product pages; API for Android/iOS cart sync — a pattern common in Indian startups serving web + mobile.

E-commerce folder organization (ShopNest)

ShopNest.Web/
├── Areas/
│   └── Admin/              ← admin-only MVC area (Article 26)
├── Controllers/
│   ├── HomeController.cs
│   ├── ProductsController.cs
│   └── CartController.cs
├── Views/
│   ├── Shared/_Layout.cshtml
│   └── Products/
├── ViewModels/
│   ├── ProductListVm.cs
│   └── CheckoutVm.cs
├── Services/               ← before splitting to Application layer
│   ├── IProductService.cs
│   └── ProductService.cs
└── wwwroot/

ShopNest.API/
├── Controllers/
│   └── ProductsController.cs
├── DTOs/
│   ├── ProductDto.cs
│   └── CreateProductRequest.cs
└── Program.cs

As ShopNest grows (Article 44), move Services/ to ShopNest.Application and EF code to ShopNest.Infrastructure — the folder layout evolves with team size.

Hands-on: scaffold ShopNest solution

dotnet new sln -n ShopNest
dotnet new mvc -n ShopNest.Web
dotnet new webapi -n ShopNest.API
dotnet sln add ShopNest.Web ShopNest.API
dotnet build

Open the solution in Visual Studio or VS Code. Identify Program.cs, launchSettings.json, and wwwroot in each project. Delete default weather/sample controllers when you recognize them — they are template noise.

Common errors

🔴 Static files 404: File not under wwwroot or UseStaticFiles() missing — add middleware before routing.

🔴 Wrong environment: Production config loaded locally — check launch profile sets Development.

🔴 Package version mismatch: EF Core 9 package with net8.0 target — align versions in .csproj.

Interview questions

Fresher

Q1: What is Program.cs?
A: Entry point that configures and runs the web host — services and middleware pipeline.

Q2: Purpose of appsettings.Development.json?
A: Environment-specific overrides when ASPNETCORE_ENVIRONMENT is Development.

Q3: What is wwwroot?
A: Web root for static files served by UseStaticFiles middleware.

Q4: What does launchSettings.json do?
A: Defines local debug profiles — URLs, ports, env vars; not used in production deployment.

Q5: Difference between bin and obj?
A: obj = intermediate compile artifacts; bin = final output DLLs and deps.

Q6: MVC vs Web API?
A: MVC returns views/HTML; Web API returns data (typically JSON) for clients.

Junior / mid

Q7: Why was Startup.cs removed?
A: Minimal hosting consolidates setup in Program.cs for clarity and less ceremony; optional extension methods split large apps.

Q8: How is configuration loaded?
A: Chain of providers — appsettings.json, environment file, User Secrets, environment variables, command line; later wins.

Senior

Q11: How would you structure a 20-developer e-commerce monolith?
A: Vertical slices or Clean Architecture folders, Areas for admin, shared kernel, strict DTO boundaries, tests per project, documented naming conventions.

Summary

  • Program.cs = DI + middleware; appsettings = config; wwwroot = static files
  • launchSettings.json is dev-only; .csproj defines framework and packages
  • ShopNest uses MVC Web + Web API + later class libraries
  • Never commit bin/obj or production secrets

Previous: Setting Up Development Environment
Next: MVC Architecture in ASP.NET Core

FAQ

Where is Startup.cs in .NET 8?

New templates inline configuration in Program.cs. You can still use a Startup class manually, but Microsoft templates no longer generate it by default.

Should ShopNest be one project or many?

Start with Web + API in one solution; split into Domain/Application/Infrastructure when complexity grows (around Article 44).

Test your knowledge

Quizzes linked to this course—pass to earn certificates.

Browse all quizzes
ASP.NET Core Complete Tutorial (ShopNest)

On this page

Introduction After this article you will Prerequisites Concept deep-dive Level 1 — Analogy Level 2 — Minimal hosting model Level 3 — ShopNest multi-project layout Every file and folder explained Program.cs deep dive appsettings.json vs Development launchSettings.json .csproj essentials wwwroot and static files MVC vs Web API project structure E-commerce folder organization (ShopNest) Hands-on: scaffold ShopNest solution Common errors Interview questions Fresher Junior / mid Senior Summary FAQ Where is Startup.cs in .NET 8? Should ShopNest be one project or many?
Module 1: Foundations
What is ASP.NET Core? Complete Guide Setting Up ASP.NET Core Development Environment ASP.NET Core Project Structure Explained MVC Architecture in ASP.NET Core — Complete Guide Controllers and Actions in ASP.NET Core Routing in ASP.NET Core — Conventional and Attribute Routing Views and Razor Syntax in ASP.NET Core Layouts, Partial Views and View Components Models and ViewModels in ASP.NET Core Forms, Model Binding and Validation in ASP.NET Core Tag Helpers in ASP.NET Core — Complete Guide Static Files, Bundling and Minification in ASP.NET Core
Module 2: Entity Framework Core
Entity Framework Core — Introduction and Setup EF Core Code First — Models, Migrations, Database EF Core CRUD Operations — Create, Read, Update, Delete EF Core LINQ Queries — Beginner to Advanced EF Core Relationships — One-to-One, One-to-Many, Many-to-Many EF Core Fluent API — Advanced Configuration EF Core Repository Pattern and Unit of Work EF Core Performance Optimization Database First Approach with EF Core (Scaffold) EF Core with SQL Server — Advanced Features
Module 3: Dependency Injection & Middleware
Dependency Injection in ASP.NET Core — Complete Guide Middleware in ASP.NET Core — Complete Guide Configuration in ASP.NET Core — appsettings, Environment Variables, Secrets Filters in ASP.NET Core — Action, Authorization, Exception, Resource, Result Logging in ASP.NET Core — ILogger, Serilog, NLog Error Handling and Exception Management in ASP.NET Core
Module 4: Authentication & Security
ASP.NET Core Identity — Complete Setup Guide Authentication in ASP.NET Core — Cookie and JWT Authorization in ASP.NET Core — Roles, Policies, Claims JWT Authentication with Refresh Tokens — Complete Implementation OAuth2 and External Login (Google, Facebook, Microsoft) Data Protection and Encryption in ASP.NET Core HTTPS, SSL Certificates and Security Best Practices
Module 5: Web API
Building REST APIs with ASP.NET Core — Complete Guide API Versioning in ASP.NET Core Swagger / OpenAPI Documentation in ASP.NET Core Input Validation in Web APIs — FluentValidation and Data Annotations Pagination, Filtering and Sorting in ASP.NET Core APIs HTTP Client and Consuming External APIs in ASP.NET Core Minimal APIs in ASP.NET Core .NET 8 SignalR — Real-Time Web Applications
Module 6: Advanced Architecture
Clean Architecture in ASP.NET Core CQRS Pattern with MediatR in ASP.NET Core Repository Pattern — Deep Dive with Generic Repository Background Services and Hosted Services in ASP.NET Core Caching in ASP.NET Core — In-Memory, Distributed, Redis Health Checks in ASP.NET Core AutoMapper in ASP.NET Core Microservices with ASP.NET Core — Introduction Message Queues with RabbitMQ / Azure Service Bus in ASP.NET Core gRPC with ASP.NET Core
Module 7: Testing
Unit Testing ASP.NET Core with xUnit and Moq Integration Testing in ASP.NET Core Testing EF Core — In-Memory vs SQLite Performance Testing and Load Testing ASP.NET Core APIs Test-Driven Development (TDD) in ASP.NET Core
Module 8: Deployment & DevOps
Deploying ASP.NET Core to IIS on Windows Server Docker and Containerization for ASP.NET Core Deploying ASP.NET Core to Azure App Service CI/CD with GitHub Actions for ASP.NET Core Azure SQL Database with ASP.NET Core Environment Configuration and Secrets Management
Module 9: Real-World Projects
Build a Complete Blog Website with ASP.NET Core MVC Build an E-Commerce Product Catalog API (ASP.NET Core Web API) Build a Student Management System (Complete CRUD App) Build a Job Portal (Full Stack ASP.NET Core) Build a REST API with Clean Architecture — Complete Guide Build a Real-Time Chat App with SignalR and ASP.NET Core
Module 10: Advanced Topics
Blazor WebAssembly and Blazor Server — Complete Guide gRPC, GraphQL and Alternative API Styles in ASP.NET Core Rate Limiting and API Throttling in ASP.NET Core .NET 8 Output Caching in ASP.NET Core .NET 8 ASP.NET Core .NET 9 New Features — Complete Guide