ASP.NET Core Web API

App Settings & The Options Pattern

1 Views Updated 5/4/2026

App Settings & The Options Pattern

Enterprise applications require configurable environments. The port your API runs on, the Database it connects to, and the API keys it uses for external services (like Stripe or AWS) must change autonomously depending on whether the app is running on your Local Laptop or the Production Server. The Options Pattern is how ASP.NET Core securely orchestrates these variables.

1. The appsettings.json Hierarchy

ASP.NET Core automatically loads configuration data in a cascading hierarchy. Variables defined in higher levels overwrite those in lower levels effortlessly.

  1. appsettings.json (Base global settings)
  2. appsettings.Development.json (Overwrites base when running locally)
  3. OS Environment Variables (Overwrites JSON; used heavily in Docker/Azure)
  4. Command Line Arguments (Absolute highest priority)

Example JSON Structure

{
  "Logging": {
    "LogLevel": { "Default": "Information" }
  },
  "PaymentGateway": {
    "StripeApiKey": "sk_test_12345",
    "MaxRetryAttempts": 3
  }
}

2. The Anti-Pattern: IConfiguration Injection

You can technically inject the raw IConfiguration interface into any controller and read the JSON via magic strings. Do not do this.

❌ Magic Strings are brittle
public class PaymentController {
    
    private readonly IConfiguration _config;
    // ...
    public void Process() {
        // If someone renames the JSON key, this silently returns NULL at runtime and crashes!
        var key = _config["PaymentGateway:StripeApiKey"]; 
    }
}

3. The Solution: The Options Pattern (Strongly Typed Config)

Instead of strings, we map the JSON section directly to a strongly-typed C# class. This provides 100% Intellisense and compile-time safety.

Step 1: Create the POCO Class

public class PaymentOptions
{
    // The property names must exactly match the JSON keys
    public string StripeApiKey { get; set; }
    public int MaxRetryAttempts { get; set; }
}

Step 2: Bind it in Program.cs

// This automatically parses the "PaymentGateway" JSON block into the PaymentOptions class
// and registers it globally in the Dependency Injection container.
builder.Services.Configure<PaymentOptions>(
    builder.Configuration.GetSection("PaymentGateway")
);

Step 3: Inject IOptions<T> into the Controller

public class PaymentController : ControllerBase
{
    private readonly PaymentOptions _paymentOptions;

    // Use IOptions to extract the strongly typed class
    public PaymentController(IOptions<PaymentOptions> options)
    {
        _paymentOptions = options.Value;
    }

    [HttpPost]
    public IActionResult Charge()
    {
        // Beautiful, strongly-typed Intellisense. No magic strings!
        var key = _paymentOptions.StripeApiKey; 
        return Ok();
    }
}

4. Interview Mastery

Q: "Can you explain the difference between IOptions, IOptionsSnapshot, and IOptionsMonitor?"

Architect Answer: "They determine how the application reacts to configuration changes *while the server is running*. IOptions registers as a Singleton on startup. If you manually edit the 'appsettings.json' file on the server while the app is running, 'IOptions' will NEVER read the new changes until you physically restart IIS. IOptionsSnapshot fixes this; it registers as Scoped. It re-reads the JSON file at the beginning of every new HTTP Request, allowing you to hot-swap configuration values in production without downtime. IOptionsMonitor is also dynamic but used specifically for Singleton services."

ASP.NET Core Web API
1. Fundamentals & HTTP
Introduction to ASP.NET Core Web API REST Principles and HTTP Methods Controllers & ControllerBase Routing (Attribute vs Conventional) Action Return Types (IActionResult)
2. Request Handling
Model Binding (FromQuery, FromBody, FromRoute) Dependency Injection (DI) Deep Dive App Settings & The Options Pattern
3. Data Access & Architecture
EF Core Setup in Web API DbContext & Migrations Repository & Unit of Work Pattern Asynchronous Programming (async/await)
4. Data Transfer & Validation
Data Transfer Objects (DTOs) & AutoMapper Model Validation (DataAnnotations) FluentValidation Integration
5. Advanced Concepts
Global Exception Handling Middleware Content Negotiation (JSON vs XML) Pagination & Filtering Advanced Searching & Sorting HATEOAS (Hypermedia) Implementation Output Caching & Response Caching
6. Security & Authorization
Cross-Origin Resource Sharing (CORS) JWT Authentication Setup Access Tokens & Refresh Tokens Workflow Role-Based & Policy-Based Authorization API Key Authentication Rate Limiting & Throttling
7. Documentation & Testing
Swagger & OpenAPI Configuration Customizing API Documentation Unit Testing Controllers (xUnit & Moq) Integration Testing (WebApplicationFactory)
8. Microservices & Deployment
Consuming External APIs (IHttpClientFactory) Health Checks & Diagnostics API Versioning Strategies Deploying APIs (Docker & Azure)