Tutorials ASP.NET Core Complete Tutorial (ShopNest)

ASP.NET Core Project Structure Explained

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.

On this page
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).

Questions on this lesson 0

Sign in to ask a question or upvote helpful answers.

No questions yet — be the first to ask!

ASP.NET Core Complete Tutorial (ShopNest)
Course syllabus
Module 1: Foundations
Module 2: Entity Framework Core
Module 3: Dependency Injection & Middleware
Module 4: Authentication & Security
Module 5: Web API
Module 6: Advanced Architecture
Module 7: Testing
Module 8: Deployment & DevOps
Module 9: Real-World Projects
Module 10: Advanced Topics
Toolliyo Assistant
Ask about tutorials, ebooks, training, pricing, mentor services, and support. I use public site content only—not admin or internal tools.

care@toolliyo.com

Need callback? Share your details