# ASP.Net Core: Understanding the framework

### **The Project Structure Overview**

When we create a new solution (e.g., named "MyApi"), Visual Studio generates this hierarchy. We will analyze them in the order they influence our application's lifecycle: from **Build** → **Boot** → **Run**.

```plaintext
MyApi/
├── MyApi.csproj                 (1. The Build Definition)
├── Properties/
│   └── launchSettings.json      (2. The Local Boot Configuration)
├── appsettings.json             (3. The Runtime Configuration)
├── appsettings.Development.json (3.1 Dev-specific overrides)
├── Program.cs                   (4. The Application Logic & Pipeline)
└── MyApi.http                   (5. The Testing Sandbox)
```

---

### **1\. The Project File (**`.csproj`)

Location: Root Folder

Purpose: Defines how the application is compiled.

How to view: Double-click the project name in Solution Explorer.

This is the foundation. It tells the .NET Compiler (Roslyn) what to do.

```xml
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
  </ItemGroup>
</Project>
```

| **Line / Section** | **Explanation** |
| --- | --- |
| `<Project Sdk="...">` | **The most important attribute.** [`Microsoft.NET`](http://Microsoft.NET)`.Sdk.Web` handles all the complexity. It automatically includes the [ASP.NET](http://ASP.NET) Core runtime, HTTP libraries, and Kestrel server. Without this, we'd just have a generic console app. |
| `<TargetFramework>` | Specifies **.NET 9.0**. This determines which version of the Common Language Runtime (CLR) will run our code. |
| `<Nullable>enable` | **Safety Feature.** This turns on "Nullable Reference Types". If we define a variable `string name;` and try to set it to `null`, the compiler will give we a warning. It forces we to write cleaner code (e.g., `string? name` for nullable). |
| `<ImplicitUsings>` | **Code Cleaner.** In older .NET, every file needed `using System; using System.Linq;` etc. This setting tells the compiler to automatically import the most common namespaces for we, keeping our files clutter-free. |
| `<PackageReference>` | **Dependencies.** This lists external libraries (NuGet packages). The `Microsoft.AspNetCore.OpenApi` package is new in .NET 9 for generating API documentation. |

---

### **2\. The Launch Settings (**`Properties/launchSettings.json`)

Location: Properties folder

Purpose: Instructions for Visual Studio on how to start the app on OUR machine.

Note: This file is ignored when we deploy to Production (Azure/AWS).

```json
{
  "$schema": "...",
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "swagger",
      "applicationUrl": "http://localhost:5012",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "https": { ... }
  }
}
```

* `profiles`: Define the different ways to start the app.
    
    * `http` / `https`: Runs the app using Kestrel (the built-in cross-platform web server). This is the preferred way for modern development.
        
    * `IIS Express`: Runs the app nested inside Windows IIS. (Legacy, usually slower).
        
* `commandName: "Project"`: Tells VS to run the executable (`MyApi.exe`) directly, rather than attaching to IIS.
    
* `launchUrl: "swagger"`: When we hit "Play", VS will open Chrome and go to [`localhost`](http://localhost)`:xxxx/swagger`.
    
* `applicationUrl`: Defines which port our computer listens on (e.g., `5012`).
    
* `ASPNETCORE_ENVIRONMENT`: **CRITICAL.** This sets the environment variable to `"Development"`.
    
    * `Program.cs` reads this to decide: "Should I show detailed error stack traces?" (Yes in Dev, No in Prod).
        

---

### **3\. The Configuration (**`appsettings.json`)

Location: Root Folder

Purpose: Global settings for the application (Database strings, API Keys, Logging).

We will see two files:

1. `appsettings.json`: The base configuration.
    
2. `appsettings.Development.json`: Overrides the base config only when `ASPNETCORE_ENVIRONMENT` is "Development".
    

```json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
```

* `Logging`: Controls the "noise level" in our output window.
    
    * `"Default": "Information"` means we see general app flow.
        
    * `"Microsoft.AspNetCore": "Warning"` silences the thousands of internal logs from the framework unless something actually breaks.
        
* `AllowedHosts`: Security setting. `"*"` means the app accepts requests from any domain name bound to the server IP.
    

---

### **4\. The Application Brain (**`Program.cs`)

Location: Root Folder

Purpose: The entry point. It builds the app, configures services, sets up the request pipeline, and starts the server.

In .NET 9, this file uses the **Minimal Hosting Model**.

#### **Part A: The Builder (Dependency Injection)**

Before the app exists, we must define what tools it has available.

```csharp
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddOpenApi();
```

* `WebApplication.CreateBuilder(args)`: This single line initializes the defaults:
    
    * Reads `appsettings.json`.
        
    * Reads Environment Variables.
        
    * Configures Kestrel.
        
* [`builder.Services`](http://builder.Services): This is the **Dependency Injection (DI) Container**.
    
    * If we want to use a Database, we must add it here ([`builder.Services`](http://builder.Services)`.AddDbContext...`).
        
    * If we want to use Auth, we add it here.
        
    * `AddOpenApi()`: Registers the services needed to generate the OpenAPI specification (swagger.json).
        

#### **Part B: The Pipeline (Middleware)**

Once `app` is built, we define how requests are handled.

```csharp
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();
```

* `app.Environment.IsDevelopment()`: Checks the variable set in `launchSettings.json`.
    
* `app.MapOpenApi()`: Creates the endpoint that serves the API documentation. We wrap it in the `if` block so random public users can't see our API internals in production.
    
* `app.UseHttpsRedirection()`: Security middleware. If a user types `http://`, this forces them to `https://`.
    

#### **Part C: The Routes (Endpoints)**

This is where the actual work happens.

```csharp
app.MapGet("/weatherforecast", () =>
{
    // ... logic to generate weather data ...
    return forecast;
})
.WithName("GetWeatherForecast");

app.Run();
```

* `MapGet`: Defines a route. "When a user sends a GET request to `/weatherforecast`, run this function."
    
* [`app.Run`](http://app.Run)`()`: The final line. It starts the infinite loop that listens for incoming network requests.
    

---

### **5\. The Testing File (**`MyApi.http`)

Location: Root Folder

Purpose: A quick way to test our API without leaving Visual Studio.

```http
@MyApi_HostAddress = http://localhost:5012

GET {{MyApi_HostAddress}}/weatherforecast/
Accept: application/json

###
```

* This is a text-based format for sending HTTP requests.
    
* We can click a small "Play" icon directly in this file in Visual Studio to send the request and see the JSON result in a side window. It replaces the need for tools like Postman for simple tests.
    

---

### **Summary of the Flow**

1. **Visual Studio** reads `.csproj` to know how to compile.
    
2. **VS** reads `launchSettings.json` to know which environment variables to set.
    
3. `Program.cs` starts:
    
    * Creates the Builder.
        
    * Reads `appsettings.json` for config.
        
    * Registers Services (DI).
        
    * **Builds the App.**
        
    * Configures Middleware (Pipeline).
        
    * Maps Routes.
        
    * **Runs** the server.
