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
- Article 2 — Development environment setup completed
dotnet --versionshows 8.0.x or 9.0.x- Optional: Article 1 — What is ASP.NET Core?
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
| Path | Purpose |
|---|---|
Program.cs | Application entry — builds host, registers services, configures middleware, runs app |
ShopNest.Web.csproj | Project manifest — target framework (net8.0), NuGet packages, build options |
appsettings.json | Default configuration (logging levels, allowed hosts, connection strings placeholder) |
appsettings.Development.json | Overrides for Development environment — detailed errors, local SQL connection |
Properties/launchSettings.json | Local 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
| Aspect | MVC (ShopNest.Web) | Web API (ShopNest.API) |
|---|---|---|
| Template | dotnet new mvc | dotnet new webapi |
| Primary output | HTML (Razor views) | JSON/XML |
| Key folders | Controllers, Views, Models, wwwroot | Controllers, sometimes DTOs folder |
| Routing | Conventional + views | Attribute routes /api/products |
| Typical use | Storefront, admin UI | Mobile 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).